From a9a0da06a72c9aa588343d23235644cab672d56e Mon Sep 17 00:00:00 2001 From: Siebe Jan Date: Mon, 20 Nov 2017 11:51:47 +0100 Subject: [PATCH 1/4] initial implementation incremental activities --- lib/hackerone/client.rb | 5 +- .../client/incremental/activities.rb | 98 +++++++++++++++++++ lib/hackerone/client/program.rb | 8 ++ lib/hackerone/client/resource_helper.rb | 15 +-- 4 files changed, 118 insertions(+), 8 deletions(-) create mode 100644 lib/hackerone/client/incremental/activities.rb diff --git a/lib/hackerone/client.rb b/lib/hackerone/client.rb index 05445f6..c5f0764 100644 --- a/lib/hackerone/client.rb +++ b/lib/hackerone/client.rb @@ -12,6 +12,7 @@ require_relative "client/structured_scope" require_relative "client/swag" require_relative "client/bounty" +require_relative "client/incremental/activities" module HackerOne module Client @@ -119,14 +120,14 @@ def get(endpoint, params = nil) self.class.parse_response(response) end - def self.parse_response(response) + def self.parse_response(response, extract_data: true) if response.status.to_s.start_with?("4") raise ArgumentError, "API called failed, probably your fault: #{response.body}" elsif response.status.to_s.start_with?("5") raise RuntimeError, "API called failed, probably their fault: #{response.body}" elsif response.success? response_body_json = JSON.parse(response.body, :symbolize_names => true) - if response_body_json.key?(:data) + if extract_data && response_body_json.key?(:data) response_body_json[:data] else response_body_json diff --git a/lib/hackerone/client/incremental/activities.rb b/lib/hackerone/client/incremental/activities.rb new file mode 100644 index 0000000..07980f0 --- /dev/null +++ b/lib/hackerone/client/incremental/activities.rb @@ -0,0 +1,98 @@ +module HackerOne + module Client + module Incremental + class Activities + include ResourceHelper + + DOTFILE = '.hackerone_client_incremental_activities'.freeze + + attr_reader :program, :updated_at_after, :page_size + + def initialize(program, updated_at_after: nil, page_size: 25) + @program = program + @updated_at_after = updated_at_after + @page_size = page_size + end + + def loop_through_activities + load_dotfile + + loop do + fetch_current_page + + activities.each do |activity_json| + activity = HackerOne::Client::Activities + .build(activity_json) + yield activity + end + + break if next_page.nil? + end + end + + def activities + current_page[:data] + end + + def next_page? + next_updated_at_after.present? + end + + def next_page + return nil unless next_page? + + @updated_at_after = next_updated_at_after + fetch_current_page + end + + def load_dotfile + return nil unless File.exist?(dotfile_filepath) + dotfile_content = JSON.parse( + File.read(dotfile_filepath) + ) + @updated_at_after = dotfile_content + .fetch(program.handle) + .fetch('updated_at_after') + end + + def store_dotfile + new_dotfile_content = { + program.handle => { + updated_at_after: updated_at_after + } + } + File.open(dotfile_filepath, 'w') do |f| + f.puts(JSON.pretty_generate(new_dotfile_content)) + end + end + + private + + def fetch_current_page + @current_page = nil + current_page + end + + def current_page + @current_page ||= make_get_request( + 'incremental/activities', + extract_data: false, + params: { + handle: program.handle, + first: page_size, + updated_at_after: updated_at_after + } + ) + end + + def dotfile_filepath + File.join(Dir.home, DOTFILE) + end + + def next_updated_at_after + current_page[:meta][:max_updated_at] + end + end + end + end +end diff --git a/lib/hackerone/client/program.rb b/lib/hackerone/client/program.rb index b71c3bd..bc3fdef 100644 --- a/lib/hackerone/client/program.rb +++ b/lib/hackerone/client/program.rb @@ -21,6 +21,14 @@ def id @program[:id] end + def incremental_activities(updated_at_after: nil, page_size: 25) + HackerOne::Client::Incremental::Activities.new( + self, + updated_at_after: updated_at_after, + page_size: page_size + ) + end + def attributes OpenStruct.new(@program[:attributes]) end diff --git a/lib/hackerone/client/resource_helper.rb b/lib/hackerone/client/resource_helper.rb index 5ce46c9..b62ea59 100644 --- a/lib/hackerone/client/resource_helper.rb +++ b/lib/hackerone/client/resource_helper.rb @@ -1,28 +1,31 @@ module HackerOne module Client module ResourceHelper - def parse_response(response) - HackerOne::Client::Api.parse_response(response) + def parse_response(response, extract_data: true) + HackerOne::Client::Api.parse_response( + response, + extract_data: extract_data, + ) end - def make_post_request(url, request_body:) + def make_post_request(url, request_body:, extract_data: true) response = HackerOne::Client::Api.hackerone_api_connection.post do |req| req.headers['Content-Type'] = 'application/json' req.url url req.body = { data: request_body }.to_json end - parse_response(response) + parse_response(response, extract_data: extract_data) end - def make_get_request(url, params: {}) + def make_get_request(url, params: {}, extract_data: true) response = HackerOne::Client::Api.hackerone_api_connection.get do |req| req.headers['Content-Type'] = 'application/json' req.url url req.params = params end - parse_response(response) + parse_response(response, extract_data: extract_data) end private From 60be35f77ff200bb936ab88457b3d421f95edb79 Mon Sep 17 00:00:00 2001 From: Siebe Jan Date: Mon, 20 Nov 2017 11:54:27 +0100 Subject: [PATCH 2/4] do not assume dotfile always contains handle --- lib/hackerone/client/incremental/activities.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/hackerone/client/incremental/activities.rb b/lib/hackerone/client/incremental/activities.rb index 07980f0..941c76c 100644 --- a/lib/hackerone/client/incremental/activities.rb +++ b/lib/hackerone/client/incremental/activities.rb @@ -50,6 +50,9 @@ def load_dotfile dotfile_content = JSON.parse( File.read(dotfile_filepath) ) + + return nil unless dotfile_content.key?(program.handle) + @updated_at_after = dotfile_content .fetch(program.handle) .fetch('updated_at_after') From b776126d4d720be78fe61d6ffe268bfcc08d1544 Mon Sep 17 00:00:00 2001 From: Siebe Jan Date: Fri, 24 Nov 2017 23:11:38 +0100 Subject: [PATCH 3/4] address comments --- .../client/incremental/activities.rb | 63 +++++-------------- 1 file changed, 14 insertions(+), 49 deletions(-) diff --git a/lib/hackerone/client/incremental/activities.rb b/lib/hackerone/client/incremental/activities.rb index 941c76c..c8f4d7b 100644 --- a/lib/hackerone/client/incremental/activities.rb +++ b/lib/hackerone/client/incremental/activities.rb @@ -4,8 +4,6 @@ module Incremental class Activities include ResourceHelper - DOTFILE = '.hackerone_client_incremental_activities'.freeze - attr_reader :program, :updated_at_after, :page_size def initialize(program, updated_at_after: nil, page_size: 25) @@ -14,15 +12,9 @@ def initialize(program, updated_at_after: nil, page_size: 25) @page_size = page_size end - def loop_through_activities - load_dotfile - + def traverse loop do - fetch_current_page - - activities.each do |activity_json| - activity = HackerOne::Client::Activities - .build(activity_json) + activities.each do |activity| yield activity end @@ -31,51 +23,28 @@ def loop_through_activities end def activities - current_page[:data] - end - - def next_page? - next_updated_at_after.present? + @activities ||= current_page[:data].map do |activity_json| + HackerOne::Client::Activities.build activity_json + end end def next_page - return nil unless next_page? + return nil unless next_cursor.present? - @updated_at_after = next_updated_at_after - fetch_current_page - end - - def load_dotfile - return nil unless File.exist?(dotfile_filepath) - dotfile_content = JSON.parse( - File.read(dotfile_filepath) - ) + # Remove memoization + @current_page = nil - return nil unless dotfile_content.key?(program.handle) + # Set cursor to next page + @updated_at_after = next_cursor - @updated_at_after = dotfile_content - .fetch(program.handle) - .fetch('updated_at_after') - end + # Fetch new page + current_page - def store_dotfile - new_dotfile_content = { - program.handle => { - updated_at_after: updated_at_after - } - } - File.open(dotfile_filepath, 'w') do |f| - f.puts(JSON.pretty_generate(new_dotfile_content)) - end + activities end private - def fetch_current_page - @current_page = nil - current_page - end - def current_page @current_page ||= make_get_request( 'incremental/activities', @@ -88,11 +57,7 @@ def current_page ) end - def dotfile_filepath - File.join(Dir.home, DOTFILE) - end - - def next_updated_at_after + def next_cursor current_page[:meta][:max_updated_at] end end From 278bdbe4bbec0c3e59d305a8722c21d7ae546068 Mon Sep 17 00:00:00 2001 From: Siebe Jan Date: Thu, 7 Dec 2017 12:25:24 +0100 Subject: [PATCH 4/4] fix + tests --- .../traverse_through_3_activities.yml | 232 +++++++++++++++ .../traverse_through_all_activities.yml | 266 ++++++++++++++++++ lib/hackerone/client/activity.rb | 7 + .../client/incremental/activities.rb | 7 +- spec/hackerone/client/program_spec.rb | 45 +++ 5 files changed, 554 insertions(+), 3 deletions(-) create mode 100644 fixtures/vcr_cassettes/traverse_through_3_activities.yml create mode 100644 fixtures/vcr_cassettes/traverse_through_all_activities.yml diff --git a/fixtures/vcr_cassettes/traverse_through_3_activities.yml b/fixtures/vcr_cassettes/traverse_through_3_activities.yml new file mode 100644 index 0000000..bb05d81 --- /dev/null +++ b/fixtures/vcr_cassettes/traverse_through_3_activities.yml @@ -0,0 +1,232 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.hackerone.com/v1/incremental/activities?first=3&handle=github&updated_at_after=2017-12-04T15:38:00%2B00:00 + body: + encoding: US-ASCII + string: '' + headers: + Authorization: + - Basic NOPE + User-Agent: + - Faraday v0.13.1 + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Dec 2017 16:24:20 GMT + Content-Type: + - application/json; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Set-Cookie: + - __cfduid=de6b363b55cc13462b7621c0ce4673ef21512491059; expires=Wed, 05-Dec-18 + 16:24:19 GMT; path=/; Domain=api.hackerone.com; HttpOnly; Secure + X-Request-Id: + - 9ed7b038-19f4-4c9e-af1f-fadc126d9a97 + Etag: + - W/"c5f96ee108dce6e865d9a927b8eada5a" + Cache-Control: + - max-age=0, private, must-revalidate + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Expect-Ct: + - enforce, max-age=86400 + Content-Security-Policy: + - 'default-src ''none''; base-uri ''self''; block-all-mixed-content; child-src + www.youtube-nocookie.com; connect-src ''self'' www.google-analytics.com errors.hackerone.net; + font-src ''self''; form-action ''self''; frame-ancestors ''none''; img-src + ''self'' data: cover-photos.hackerone-user-content.com hackathon-photos.hackerone-user-content.com + profile-photos.hackerone-user-content.com hackerone-attachments.s3.amazonaws.com; + media-src ''self'' hackerone-attachments.s3.amazonaws.com; script-src ''self'' + www.google-analytics.com; style-src ''self'' ''unsafe-inline''; report-uri + https://errors.hackerone.net/api/30/csp-report/?sentry_key=61c1e2f50d21487c97a071737701f598' + Referrer-Policy: + - strict-origin-when-cross-origin + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Frame-Options: + - DENY + X-Permitted-Cross-Domain-Policies: + - none + X-Xss-Protection: + - 1; mode=block + Server: + - cloudflare-nginx + Cf-Ray: + - 3c885ae2caba2bfa-AMS + body: + encoding: ASCII-8BIT + string: '{"data":[{"type":"activity-group-assigned-to-bug","id":"2198958","attributes":{"message":"","created_at":"2017-12-04T15:38:00.017Z","updated_at":"2017-12-04T15:38:00.017Z","internal":true},"relationships":{"actor":{"data":{"type":"user","id":"114514","attributes":{"username":"kerkkerkkekr","name":"kerk + kerk","disabled":false,"created_at":"2016-09-29T12:52:29.551Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}},"group":{"data":{"id":"16481","type":"group","attributes":{"name":"Standard","created_at":"2016-09-29T12:52:32.062Z","permissions":["report_management","reward_management"]}}}}},{"type":"activity-comment","id":"2201959","attributes":{"message":"this + is a comment","created_at":"2017-12-05T16:16:07.205Z","updated_at":"2017-12-05T16:16:07.205Z","internal":true},"relationships":{"actor":{"data":{"type":"user","id":"114514","attributes":{"username":"kerkkerkkekr","name":"kerk + kerk","disabled":false,"created_at":"2016-09-29T12:52:29.551Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-bounty-awarded","id":"2201960","attributes":{"message":"Here''s + a bounty!","created_at":"2017-12-05T16:16:27.757Z","updated_at":"2017-12-05T16:16:27.757Z","internal":false,"bounty_amount":"250"},"relationships":{"actor":{"data":{"type":"user","id":"114514","attributes":{"username":"kerkkerkkekr","name":"kerk + kerk","disabled":false,"created_at":"2016-09-29T12:52:29.551Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}}],"meta":{"max_updated_at":"2017-12-05T16:16:27.757Z"}}' + http_version: + recorded_at: Tue, 05 Dec 2017 16:24:20 GMT +- request: + method: get + uri: https://api.hackerone.com/v1/incremental/activities?first=3&handle=github&updated_at_after=2017-12-04T15:38:00%2B00:00 + body: + encoding: US-ASCII + string: '' + headers: + Authorization: + - Basic NOPE + User-Agent: + - Faraday v0.13.1 + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Dec 2017 16:24:31 GMT + Content-Type: + - application/json; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Set-Cookie: + - __cfduid=d9b2c3597c39ebf83d782cb04956600fb1512491070; expires=Wed, 05-Dec-18 + 16:24:30 GMT; path=/; Domain=api.hackerone.com; HttpOnly; Secure + X-Request-Id: + - 9e88cbb0-7040-4b64-9fc5-dc9a78be3a56 + Etag: + - W/"c5f96ee108dce6e865d9a927b8eada5a" + Cache-Control: + - max-age=0, private, must-revalidate + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Expect-Ct: + - enforce, max-age=86400 + Content-Security-Policy: + - 'default-src ''none''; base-uri ''self''; block-all-mixed-content; child-src + www.youtube-nocookie.com; connect-src ''self'' www.google-analytics.com errors.hackerone.net; + font-src ''self''; form-action ''self''; frame-ancestors ''none''; img-src + ''self'' data: cover-photos.hackerone-user-content.com hackathon-photos.hackerone-user-content.com + profile-photos.hackerone-user-content.com hackerone-attachments.s3.amazonaws.com; + media-src ''self'' hackerone-attachments.s3.amazonaws.com; script-src ''self'' + www.google-analytics.com; style-src ''self'' ''unsafe-inline''; report-uri + https://errors.hackerone.net/api/30/csp-report/?sentry_key=61c1e2f50d21487c97a071737701f598' + Referrer-Policy: + - strict-origin-when-cross-origin + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Frame-Options: + - DENY + X-Permitted-Cross-Domain-Policies: + - none + X-Xss-Protection: + - 1; mode=block + Server: + - cloudflare-nginx + Cf-Ray: + - 3c885b264b3d72f5-AMS + body: + encoding: ASCII-8BIT + string: '{"data":[{"type":"activity-group-assigned-to-bug","id":"2198958","attributes":{"message":"","created_at":"2017-12-04T15:38:00.017Z","updated_at":"2017-12-04T15:38:00.017Z","internal":true},"relationships":{"actor":{"data":{"type":"user","id":"114514","attributes":{"username":"kerkkerkkekr","name":"kerk + kerk","disabled":false,"created_at":"2016-09-29T12:52:29.551Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}},"group":{"data":{"id":"16481","type":"group","attributes":{"name":"Standard","created_at":"2016-09-29T12:52:32.062Z","permissions":["report_management","reward_management"]}}}}},{"type":"activity-comment","id":"2201959","attributes":{"message":"this + is a comment","created_at":"2017-12-05T16:16:07.205Z","updated_at":"2017-12-05T16:16:07.205Z","internal":true},"relationships":{"actor":{"data":{"type":"user","id":"114514","attributes":{"username":"kerkkerkkekr","name":"kerk + kerk","disabled":false,"created_at":"2016-09-29T12:52:29.551Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-bounty-awarded","id":"2201960","attributes":{"message":"Here''s + a bounty!","created_at":"2017-12-05T16:16:27.757Z","updated_at":"2017-12-05T16:16:27.757Z","internal":false,"bounty_amount":"250"},"relationships":{"actor":{"data":{"type":"user","id":"114514","attributes":{"username":"kerkkerkkekr","name":"kerk + kerk","disabled":false,"created_at":"2016-09-29T12:52:29.551Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}}],"meta":{"max_updated_at":"2017-12-05T16:16:27.757Z"}}' + http_version: + recorded_at: Tue, 05 Dec 2017 16:24:30 GMT +- request: + method: get + uri: https://api.hackerone.com/v1/incremental/activities?first=3&handle=github&updated_at_after=2017-12-05T16:16:27.757Z + body: + encoding: US-ASCII + string: '' + headers: + Authorization: + - Basic NOPE + User-Agent: + - Faraday v0.13.1 + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Tue, 05 Dec 2017 16:24:54 GMT + Content-Type: + - application/json; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Set-Cookie: + - __cfduid=dc43387e7a367ab6fa7b1183b4fba44b91512491093; expires=Wed, 05-Dec-18 + 16:24:53 GMT; path=/; Domain=api.hackerone.com; HttpOnly; Secure + X-Request-Id: + - 863a8f3a-060e-40ef-831d-9c2ef6d995ce + Etag: + - W/"79b5a37965df910984602c8925f27ef9" + Cache-Control: + - max-age=0, private, must-revalidate + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Expect-Ct: + - enforce, max-age=86400 + Content-Security-Policy: + - 'default-src ''none''; base-uri ''self''; block-all-mixed-content; child-src + www.youtube-nocookie.com; connect-src ''self'' www.google-analytics.com errors.hackerone.net; + font-src ''self''; form-action ''self''; frame-ancestors ''none''; img-src + ''self'' data: cover-photos.hackerone-user-content.com hackathon-photos.hackerone-user-content.com + profile-photos.hackerone-user-content.com hackerone-attachments.s3.amazonaws.com; + media-src ''self'' hackerone-attachments.s3.amazonaws.com; script-src ''self'' + www.google-analytics.com; style-src ''self'' ''unsafe-inline''; report-uri + https://errors.hackerone.net/api/30/csp-report/?sentry_key=61c1e2f50d21487c97a071737701f598' + Referrer-Policy: + - strict-origin-when-cross-origin + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Frame-Options: + - DENY + X-Permitted-Cross-Domain-Policies: + - none + X-Xss-Protection: + - 1; mode=block + Server: + - cloudflare-nginx + Cf-Ray: + - 3c885bb88be672f5-AMS + body: + encoding: ASCII-8BIT + string: '{"data":[],"meta":{"max_updated_at":null}}' + http_version: + recorded_at: Tue, 05 Dec 2017 16:24:53 GMT +recorded_with: VCR 3.0.3 diff --git a/fixtures/vcr_cassettes/traverse_through_all_activities.yml b/fixtures/vcr_cassettes/traverse_through_all_activities.yml new file mode 100644 index 0000000..370c0fd --- /dev/null +++ b/fixtures/vcr_cassettes/traverse_through_all_activities.yml @@ -0,0 +1,266 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.hackerone.com/v1/incremental/activities?first=25&handle=github&updated_at_after + body: + encoding: US-ASCII + string: '' + headers: + Authorization: + - Basic NOPE + User-Agent: + - Faraday v0.13.1 + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 07 Dec 2017 11:20:42 GMT + Content-Type: + - application/json; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Set-Cookie: + - __cfduid=d1cd9fb34dc4cf47e72804e2f7cadd6b81512645641; expires=Fri, 07-Dec-18 + 11:20:41 GMT; path=/; Domain=api.hackerone.com; HttpOnly; Secure + X-Request-Id: + - d0445113-cfbb-4907-8e6d-a93922e5c5c3 + Etag: + - W/"dd2824639dd19b9d08e8a1c4692f556e" + Cache-Control: + - max-age=0, private, must-revalidate + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Expect-Ct: + - enforce, max-age=86400 + Content-Security-Policy: + - 'default-src ''none''; base-uri ''self''; block-all-mixed-content; child-src + www.youtube-nocookie.com; connect-src ''self'' www.google-analytics.com errors.hackerone.net; + font-src ''self''; form-action ''self''; frame-ancestors ''none''; img-src + ''self'' data: cover-photos.hackerone-user-content.com hackathon-photos.hackerone-user-content.com + profile-photos.hackerone-user-content.com hackerone-attachments.s3.amazonaws.com; + media-src ''self'' hackerone-attachments.s3.amazonaws.com; script-src ''self'' + www.google-analytics.com; style-src ''self'' ''unsafe-inline''; report-uri + https://errors.hackerone.net/api/30/csp-report/?sentry_key=61c1e2f50d21487c97a071737701f598' + Referrer-Policy: + - strict-origin-when-cross-origin + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Frame-Options: + - DENY + X-Permitted-Cross-Domain-Policies: + - none + X-Xss-Protection: + - 1; mode=block + Server: + - cloudflare-nginx + Cf-Ray: + - 3c9718dc4bd50755-AMS + body: + encoding: ASCII-8BIT + string: '{"data":[{"type":"activity-bug-filed","id":"1223485","attributes":{"message":"","created_at":"2016-09-29T12:53:30.516Z","updated_at":"2016-09-29T12:53:30.516Z","internal":false},"relationships":{"actor":{"data":{"type":"user","id":"3683","attributes":{"username":"demo-hacker","name":"Demo + Hacker","disabled":false,"created_at":"2014-03-17T20:14:25.383Z","profile_picture":{"62x62":"https://profile-photos.hackerone-user-content.com/production/000/003/683/93c0f225152f8f18a396f325eca530143719a729_small.png?1423472503","82x82":"https://profile-photos.hackerone-user-content.com/production/000/003/683/d38d82a37a6ac1f2df43b0d36ad8ee8d0acd68d1_medium.png?1423472503","110x110":"https://profile-photos.hackerone-user-content.com/production/000/003/683/6793a1566a8c8ec72a179c63bbd92c1af965a162_large.png?1423472503","260x260":"https://profile-photos.hackerone-user-content.com/production/000/003/683/0201a343075ea8f7feb7aff975c6a48cc53536c7_xtralarge.png?1423472503"}}}}}},{"type":"activity-comment","id":"1223486","attributes":{"message":"As + a team manager you can [edit your program](https://hackerone.com/github/edit) + and [invite other team members](https://hackerone.com/github/team_members).\n","created_at":"2016-09-29T12:53:30.638Z","updated_at":"2016-09-29T12:53:30.638Z","internal":true},"relationships":{"actor":{"data":{"type":"user","id":"4954","attributes":{"username":"demo-member","name":"Demo + Member","disabled":false,"created_at":"2014-04-14T11:45:00.949Z","profile_picture":{"62x62":"https://profile-photos.hackerone-user-content.com/production/000/004/954/76e628d12eaacde79878b890df02c065f740b1a4_small.png?1423472456","82x82":"https://profile-photos.hackerone-user-content.com/production/000/004/954/75e4cf2599f591e618646429db57d986e496ccee_medium.png?1423472456","110x110":"https://profile-photos.hackerone-user-content.com/production/000/004/954/25f5c8af70323cacb2c2ffa17d68cac2500dc410_large.png?1423472456","260x260":"https://profile-photos.hackerone-user-content.com/production/000/004/954/d903c042cdc7798ad76684563624ee7ea071aed8_xtralarge.png?1423472456"}}}}}},{"type":"activity-user-assigned-to-bug","id":"1223487","attributes":{"message":"A + new report! @kerkkerkkekr, can you take a look at this?\n\n* Need more information? + *Change state: Needs more info*\n* Ready to get started on a fix? *Change + state: Triaged*\n* Job''s done? *Close report: Resolved*\n\nNeed a hand? Just + say the word and a HackerOne engineer will materialize, as if by magic.\n","created_at":"2016-09-29T12:53:30.780Z","updated_at":"2016-09-29T12:53:30.780Z","internal":true},"relationships":{"actor":{"data":{"type":"user","id":"4954","attributes":{"username":"demo-member","name":"Demo + Member","disabled":false,"created_at":"2014-04-14T11:45:00.949Z","profile_picture":{"62x62":"https://profile-photos.hackerone-user-content.com/production/000/004/954/76e628d12eaacde79878b890df02c065f740b1a4_small.png?1423472456","82x82":"https://profile-photos.hackerone-user-content.com/production/000/004/954/75e4cf2599f591e618646429db57d986e496ccee_medium.png?1423472456","110x110":"https://profile-photos.hackerone-user-content.com/production/000/004/954/25f5c8af70323cacb2c2ffa17d68cac2500dc410_large.png?1423472456","260x260":"https://profile-photos.hackerone-user-content.com/production/000/004/954/d903c042cdc7798ad76684563624ee7ea071aed8_xtralarge.png?1423472456"}}}},"assigned_user":{"data":{"id":"114514","type":"user","attributes":{"username":"kerkkerkkekr","name":"kerk + kerk","disabled":false,"created_at":"2016-09-29T12:52:29.551Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-comment","id":"1223489","attributes":{"message":"test\n","created_at":"2016-09-29T12:55:06.095Z","updated_at":"2016-09-29T12:55:06.095Z","internal":false},"relationships":{"actor":{"data":{"type":"user","id":"114514","attributes":{"username":"kerkkerkkekr","name":"kerk + kerk","disabled":false,"created_at":"2016-09-29T12:52:29.551Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-bug-not-applicable","id":"1223490","attributes":{"message":"Automated + vulnerability scanners commonly have low priority issues and/or false positives. + Before submitting the results from a scanner, please take a moment to confirm + that the reported issues are actually valid and exploitable. In this specific + case, many cookies intentionally lack the `HttpOnly` flag so that they can + be accessed from JavaScript. This only introduces a potential risk if the + cookie in question contains session data or other sensitive information.\n","created_at":"2016-09-29T12:55:17.179Z","updated_at":"2016-09-29T12:55:17.179Z","internal":false},"relationships":{"actor":{"data":{"type":"user","id":"114514","attributes":{"username":"kerkkerkkekr","name":"kerk + kerk","disabled":false,"created_at":"2016-09-29T12:52:29.551Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-comment","id":"1223491","attributes":{"message":"Sorry, + I''ll avoid these types of reports in the future.\n","created_at":"2016-09-29T12:55:17.244Z","updated_at":"2016-09-29T12:55:17.244Z","internal":false},"relationships":{"actor":{"data":{"type":"user","id":"3683","attributes":{"username":"demo-hacker","name":"Demo + Hacker","disabled":false,"created_at":"2014-03-17T20:14:25.383Z","profile_picture":{"62x62":"https://profile-photos.hackerone-user-content.com/production/000/003/683/93c0f225152f8f18a396f325eca530143719a729_small.png?1423472503","82x82":"https://profile-photos.hackerone-user-content.com/production/000/003/683/d38d82a37a6ac1f2df43b0d36ad8ee8d0acd68d1_medium.png?1423472503","110x110":"https://profile-photos.hackerone-user-content.com/production/000/003/683/6793a1566a8c8ec72a179c63bbd92c1af965a162_large.png?1423472503","260x260":"https://profile-photos.hackerone-user-content.com/production/000/003/683/0201a343075ea8f7feb7aff975c6a48cc53536c7_xtralarge.png?1423472503"}}}}}},{"type":"activity-bug-filed","id":"1223750","attributes":{"message":"","created_at":"2016-09-29T15:21:02.759Z","updated_at":"2016-09-29T15:21:02.759Z","internal":false},"relationships":{"actor":{"data":{"type":"user","id":"114514","attributes":{"username":"kerkkerkkekr","name":"kerk + kerk","disabled":false,"created_at":"2016-09-29T12:52:29.551Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-reference-id-added","id":"1532364","attributes":{"message":"","created_at":"2017-03-10T14:03:20.780Z","updated_at":"2017-03-10T14:03:20.780Z","internal":true,"reference":"TEST-4","reference_url":"https://h1test.atlassian.net/browse/TEST-4"},"relationships":{"actor":{"data":{"type":"user","id":"114514","attributes":{"username":"kerkkerkkekr","name":"kerk + kerk","disabled":false,"created_at":"2016-09-29T12:52:29.551Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-comment","id":"1540105","attributes":{"message":"The + [JIRA issue](https://h1test.atlassian.net/browse/TEST-4) associated with this + report was modified.\n\n- **Status**: changed from *Closed* to *Reopened*.\n- + **Resolution**: changed from *Done* to **.","created_at":"2017-03-14T13:42:54.857Z","updated_at":"2017-03-14T13:42:54.857Z","internal":true},"relationships":{"actor":{"data":{"type":"user","id":"20889","attributes":{"username":"hackbot","name":"","disabled":false,"created_at":"2015-04-21T14:15:00.516Z","profile_picture":{"62x62":"https://profile-photos.hackerone-user-content.com/production/000/020/889/d4e1fd3399b43d7555eba2cc7b21c48fa4ffb4ae_small.png?1429625702","82x82":"https://profile-photos.hackerone-user-content.com/production/000/020/889/dd4834fa15b3684705d2af84f8f3acd23a52cd29_medium.png?1429625702","110x110":"https://profile-photos.hackerone-user-content.com/production/000/020/889/8afcf976d18ed73dc799259ac5f80ab0f81f1f22_large.png?1429625702","260x260":"https://profile-photos.hackerone-user-content.com/production/000/020/889/7df97703a6b5797e4e64373b9ee6b31a04f2e273_xtralarge.png?1429625702"}}}}}},{"type":"activity-nobody-assigned-to-bug","id":"1703337","attributes":{"message":null,"created_at":"2017-05-26T12:50:26.425Z","updated_at":"2017-05-26T12:50:26.425Z","internal":true},"relationships":{"actor":{"data":{"type":"user","id":"171202","attributes":{"username":"api_v5tad85sqjf06ljgu7vjm","name":"","disabled":true,"created_at":"2017-05-26T12:45:03.089Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-nobody-assigned-to-bug","id":"1703338","attributes":{"message":null,"created_at":"2017-05-26T12:50:28.545Z","updated_at":"2017-05-26T12:50:28.545Z","internal":true},"relationships":{"actor":{"data":{"type":"user","id":"171202","attributes":{"username":"api_v5tad85sqjf06ljgu7vjm","name":"","disabled":true,"created_at":"2017-05-26T12:45:03.089Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-bounty-suggested","id":"1946221","attributes":{"message":"api + test!","created_at":"2017-08-22T13:21:57.024Z","updated_at":"2017-08-22T13:21:57.024Z","internal":true,"bounty_amount":"1","bonus_amount":"0"},"relationships":{"actor":{"data":{"type":"user","id":"193855","attributes":{"username":"api_kiqgkxdhsux76a1t2a8k1","name":"","disabled":true,"created_at":"2017-08-22T13:18:29.084Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-bounty-awarded","id":"1946223","attributes":{"message":"sandbox!","created_at":"2017-08-22T13:22:55.331Z","updated_at":"2017-08-22T13:22:55.331Z","internal":false,"bounty_amount":"50"},"relationships":{"actor":{"data":{"type":"user","id":"193855","attributes":{"username":"api_kiqgkxdhsux76a1t2a8k1","name":"","disabled":true,"created_at":"2017-08-22T13:18:29.084Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-bounty-awarded","id":"1946450","attributes":{"message":"Thanks + for the great report!","created_at":"2017-08-22T15:03:46.193Z","updated_at":"2017-08-22T15:03:46.193Z","internal":false,"bounty_amount":"1,330","bonus_amount":"7"},"relationships":{"actor":{"data":{"type":"user","id":"193855","attributes":{"username":"api_kiqgkxdhsux76a1t2a8k1","name":"","disabled":true,"created_at":"2017-08-22T13:18:29.084Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-bounty-awarded","id":"1946460","attributes":{"message":"This + report is great, I think we should award a high bounty.","created_at":"2017-08-22T15:06:16.585Z","updated_at":"2017-08-22T15:06:16.585Z","internal":false,"bounty_amount":"5,000","bonus_amount":"2,500"},"relationships":{"actor":{"data":{"type":"user","id":"193855","attributes":{"username":"api_kiqgkxdhsux76a1t2a8k1","name":"","disabled":true,"created_at":"2017-08-22T13:18:29.084Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-bounty-suggested","id":"1946462","attributes":{"message":"This + report is great, I think we should award a high bounty.","created_at":"2017-08-22T15:06:29.310Z","updated_at":"2017-08-22T15:06:29.310Z","internal":true,"bounty_amount":"5,000","bonus_amount":"2,500"},"relationships":{"actor":{"data":{"type":"user","id":"193855","attributes":{"username":"api_kiqgkxdhsux76a1t2a8k1","name":"","disabled":true,"created_at":"2017-08-22T13:18:29.084Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-swag-awarded","id":"1946479","attributes":{"message":"Enjoy + this cool swag!","created_at":"2017-08-22T15:09:44.191Z","updated_at":"2017-08-22T15:09:44.191Z","internal":false},"relationships":{"actor":{"data":{"type":"program","id":"15567","attributes":{"handle":"github","created_at":"2016-09-29T12:52:30.755Z","updated_at":"2017-12-07T03:34:15.104Z"}}},"swag":{"data":{"id":"2057","type":"swag","attributes":{"sent":false,"created_at":"2017-08-22T15:09:44.176Z"}}}}},{"type":"activity-bounty-suggested","id":"1946481","attributes":{"message":"This + report is great, I think we should award a high bounty.","created_at":"2017-08-22T15:10:02.699Z","updated_at":"2017-08-22T15:10:02.699Z","internal":true,"bounty_amount":"5,000","bonus_amount":"2,500"},"relationships":{"actor":{"data":{"type":"user","id":"193855","attributes":{"username":"api_kiqgkxdhsux76a1t2a8k1","name":"","disabled":true,"created_at":"2017-08-22T13:18:29.084Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-bounty-awarded","id":"1959177","attributes":{"message":"Thanks + for the great report. Here''s your bounty!","created_at":"2017-08-28T09:15:14.581Z","updated_at":"2017-08-28T09:15:14.581Z","internal":false,"bounty_amount":"500","bonus_amount":"250"},"relationships":{"actor":{"data":{"type":"user","id":"195420","attributes":{"username":"api_i9w8kxzbitav5iot5tecd","name":"","disabled":true,"created_at":"2017-08-28T09:13:03.805Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-bounty-awarded","id":"1959178","attributes":{"message":"Thanks + for the great report. Here''s your bounty!","created_at":"2017-08-28T09:15:44.797Z","updated_at":"2017-08-28T09:15:44.797Z","internal":false,"bounty_amount":"500","bonus_amount":"250"},"relationships":{"actor":{"data":{"type":"user","id":"195420","attributes":{"username":"api_i9w8kxzbitav5iot5tecd","name":"","disabled":true,"created_at":"2017-08-28T09:13:03.805Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-bounty-suggested","id":"1959180","attributes":{"message":"This + report is great, I think we should award a high bounty","created_at":"2017-08-28T09:21:00.321Z","updated_at":"2017-08-28T09:21:00.321Z","internal":true,"bounty_amount":"5,000","bonus_amount":"2,500"},"relationships":{"actor":{"data":{"type":"user","id":"195420","attributes":{"username":"api_i9w8kxzbitav5iot5tecd","name":"","disabled":true,"created_at":"2017-08-28T09:13:03.805Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-swag-awarded","id":"1959183","attributes":{"message":"This + is the 5th report we received from you. We''d like to send you a shirt and + some stickers as a small thank-you!","created_at":"2017-08-28T09:22:30.759Z","updated_at":"2017-08-28T09:22:30.759Z","internal":false},"relationships":{"actor":{"data":{"type":"program","id":"15567","attributes":{"handle":"github","created_at":"2016-09-29T12:52:30.755Z","updated_at":"2017-12-07T03:34:15.104Z"}}},"swag":{"data":{"id":"2066","type":"swag","attributes":{"sent":false,"created_at":"2017-08-28T09:22:30.752Z"}}}}},{"type":"activity-comment","id":"2013988","attributes":{"message":"attachment + test {F223036}","created_at":"2017-09-22T11:16:01.234Z","updated_at":"2017-09-22T11:16:01.234Z","internal":true},"relationships":{"actor":{"data":{"type":"user","id":"114514","attributes":{"username":"kerkkerkkekr","name":"kerk + kerk","disabled":false,"created_at":"2016-09-29T12:52:29.551Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}},"attachments":{"data":[{"id":"223036","type":"attachment","attributes":{"expiring_url":"https://hackerone-attachments.s3.amazonaws.com/production/000/223/036/1de5763ba46272c006e580ed77a54849f00897da/no_fun_allowed.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Credential=ASIAIENMAGUODLNT7Y7A%2F20171207%2Fus-east-1%2Fs3%2Faws4_request\u0026X-Amz-Date=20171207T112042Z\u0026X-Amz-Expires=3600\u0026X-Amz-Security-Token=FQoDYXdzEIz%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaDCcD%2BtaI50vSjaM%2B%2FiK3A%2FIQNveLUurXbSCni%2FS0YeW7tgrxeOcF%2FlysL95bxqdhCcRN9l2vXLKassGCpKiAAsPjeoM8FiTVFS5Rm%2FBopuzfQ2aKhRkD0lWne0yHq46RSlvyTpR4Gz3VE%2BPWYIvb2pDo1rv79VGd2GJT2xCKhJHpCmG7OckSsOvbT9tT42zWuzR5qYhQIuQHALH8S1EMDhOgIvLlu2xAfnOPfgxeixt68o0%2BkBb68zfiTT496OPgwxEEDZ%2B5dxHAbaUZs%2F4vUTPdUcmQ%2FHWdG5TeXEsylFylqsEKMKYLVKZh4N60Zn1Nf17MELrRiBYFxq8JvdT6gs4mYpATas9oRlAnXz8Mo02vexBhuV0xeBFMk%2FhUwNNaVyGJLEuyAw1EEtwo82ychlui3wwG5X0%2BFW7pc57mrqVmOGK39mL0H2fK01mhy%2BEWG2L4J5TkZ0B13I6DjaVwVMb0jnwjHTuhgDsS7Kyycxoktz3fMqPUofyIQmkz2FkfbtN5W1tjVFtnlpJAPF87nYRHW2qWoVcSjps9zsuwSXzOZlG7hV5UKw6g3Do9l78Ly36CX6z54KbA%2FylADltWOgao9wesoNAojq2k0QU%3D\u0026X-Amz-SignedHeaders=host\u0026X-Amz-Signature=f45c2af07ffd691285d2eca214172446b0840583637dc5fda48cad1fba5869ee","created_at":"2017-09-22T11:15:45.677Z","file_name":"no_fun_allowed.jpg","content_type":"image/jpeg","file_size":86501}}]}}},{"type":"activity-user-assigned-to-bug","id":"2110465","attributes":{"message":null,"created_at":"2017-10-28T18:15:04.285Z","updated_at":"2017-10-28T18:15:04.285Z","internal":true},"relationships":{"actor":{"data":{"type":"user","id":"212530","attributes":{"username":"api_givg6fpvnisu7pcxu4snoc9fxc","name":"","disabled":true,"created_at":"2017-10-28T17:46:26.037Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}},"assigned_user":{"data":{"id":"114514","type":"user","attributes":{"username":"kerkkerkkekr","name":"kerk + kerk","disabled":false,"created_at":"2016-09-29T12:52:29.551Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-group-assigned-to-bug","id":"2198958","attributes":{"message":"","created_at":"2017-12-04T15:38:00.017Z","updated_at":"2017-12-04T15:38:00.017Z","internal":true},"relationships":{"actor":{"data":{"type":"user","id":"114514","attributes":{"username":"kerkkerkkekr","name":"kerk + kerk","disabled":false,"created_at":"2016-09-29T12:52:29.551Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}},"group":{"data":{"id":"16481","type":"group","attributes":{"name":"Standard","created_at":"2016-09-29T12:52:32.062Z","permissions":["report_management","reward_management"]}}}}}],"meta":{"max_updated_at":"2017-12-04T15:38:00.017Z"}}' + http_version: + recorded_at: Thu, 07 Dec 2017 11:20:42 GMT +- request: + method: get + uri: https://api.hackerone.com/v1/incremental/activities?first=25&handle=github&updated_at_after=2017-12-04T15:38:00.017Z + body: + encoding: US-ASCII + string: '' + headers: + Authorization: + - Basic NOPE + User-Agent: + - Faraday v0.13.1 + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 07 Dec 2017 11:20:43 GMT + Content-Type: + - application/json; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Set-Cookie: + - __cfduid=d7f2e9e687c54598f2e5daa3699e6a3181512645642; expires=Fri, 07-Dec-18 + 11:20:42 GMT; path=/; Domain=api.hackerone.com; HttpOnly; Secure + X-Request-Id: + - bf815a7b-35a6-438d-8198-618dd9f163c3 + Etag: + - W/"f057e5758c4dd46ef847c8a49303a160" + Cache-Control: + - max-age=0, private, must-revalidate + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Expect-Ct: + - enforce, max-age=86400 + Content-Security-Policy: + - 'default-src ''none''; base-uri ''self''; block-all-mixed-content; child-src + www.youtube-nocookie.com; connect-src ''self'' www.google-analytics.com errors.hackerone.net; + font-src ''self''; form-action ''self''; frame-ancestors ''none''; img-src + ''self'' data: cover-photos.hackerone-user-content.com hackathon-photos.hackerone-user-content.com + profile-photos.hackerone-user-content.com hackerone-attachments.s3.amazonaws.com; + media-src ''self'' hackerone-attachments.s3.amazonaws.com; script-src ''self'' + www.google-analytics.com; style-src ''self'' ''unsafe-inline''; report-uri + https://errors.hackerone.net/api/30/csp-report/?sentry_key=61c1e2f50d21487c97a071737701f598' + Referrer-Policy: + - strict-origin-when-cross-origin + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Frame-Options: + - DENY + X-Permitted-Cross-Domain-Policies: + - none + X-Xss-Protection: + - 1; mode=block + Server: + - cloudflare-nginx + Cf-Ray: + - 3c9718e47b549d0e-AMS + body: + encoding: ASCII-8BIT + string: '{"data":[{"type":"activity-comment","id":"2201959","attributes":{"message":"this + is a comment","created_at":"2017-12-05T16:16:07.205Z","updated_at":"2017-12-05T16:16:07.205Z","internal":true},"relationships":{"actor":{"data":{"type":"user","id":"114514","attributes":{"username":"kerkkerkkekr","name":"kerk + kerk","disabled":false,"created_at":"2016-09-29T12:52:29.551Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}},{"type":"activity-bounty-awarded","id":"2201960","attributes":{"message":"Here''s + a bounty!","created_at":"2017-12-05T16:16:27.757Z","updated_at":"2017-12-05T16:16:27.757Z","internal":false,"bounty_amount":"250"},"relationships":{"actor":{"data":{"type":"user","id":"114514","attributes":{"username":"kerkkerkkekr","name":"kerk + kerk","disabled":false,"created_at":"2016-09-29T12:52:29.551Z","profile_picture":{"62x62":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","82x82":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","110x110":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png","260x260":"/assets/avatars/default-71a302d706457f3d3a31eb30fa3e73e6cf0b1d677b8fa218eaeaffd67ae97918.png"}}}}}}],"meta":{"max_updated_at":"2017-12-05T16:16:27.757Z"}}' + http_version: + recorded_at: Thu, 07 Dec 2017 11:20:43 GMT +- request: + method: get + uri: https://api.hackerone.com/v1/incremental/activities?first=25&handle=github&updated_at_after=2017-12-05T16:16:27.757Z + body: + encoding: US-ASCII + string: '' + headers: + Authorization: + - Basic NOPE + User-Agent: + - Faraday v0.13.1 + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 07 Dec 2017 11:20:44 GMT + Content-Type: + - application/json; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Set-Cookie: + - __cfduid=d59112f789e4ddbe951f904df9b223f041512645643; expires=Fri, 07-Dec-18 + 11:20:43 GMT; path=/; Domain=api.hackerone.com; HttpOnly; Secure + X-Request-Id: + - '09aee1e6-00a2-4be0-8c7a-eac354c05341' + Etag: + - W/"79b5a37965df910984602c8925f27ef9" + Cache-Control: + - max-age=0, private, must-revalidate + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Expect-Ct: + - enforce, max-age=86400 + Content-Security-Policy: + - 'default-src ''none''; base-uri ''self''; block-all-mixed-content; child-src + www.youtube-nocookie.com; connect-src ''self'' www.google-analytics.com errors.hackerone.net; + font-src ''self''; form-action ''self''; frame-ancestors ''none''; img-src + ''self'' data: cover-photos.hackerone-user-content.com hackathon-photos.hackerone-user-content.com + profile-photos.hackerone-user-content.com hackerone-attachments.s3.amazonaws.com; + media-src ''self'' hackerone-attachments.s3.amazonaws.com; script-src ''self'' + www.google-analytics.com; style-src ''self'' ''unsafe-inline''; report-uri + https://errors.hackerone.net/api/30/csp-report/?sentry_key=61c1e2f50d21487c97a071737701f598' + Referrer-Policy: + - strict-origin-when-cross-origin + X-Content-Type-Options: + - nosniff + X-Download-Options: + - noopen + X-Frame-Options: + - DENY + X-Permitted-Cross-Domain-Policies: + - none + X-Xss-Protection: + - 1; mode=block + Server: + - cloudflare-nginx + Cf-Ray: + - 3c9718e9ac932bc4-AMS + body: + encoding: ASCII-8BIT + string: '{"data":[],"meta":{"max_updated_at":null}}' + http_version: + recorded_at: Thu, 07 Dec 2017 11:20:44 GMT +recorded_with: VCR 3.0.3 diff --git a/lib/hackerone/client/activity.rb b/lib/hackerone/client/activity.rb index 5538d05..aa9b284 100644 --- a/lib/hackerone/client/activity.rb +++ b/lib/hackerone/client/activity.rb @@ -46,6 +46,12 @@ class UserAssignedToBug < Activity delegate :assigned_user, to: :relationships end + class GroupAssignedToBug < Activity + def group + HackerOne::Client::Group.new(relationships.group[:data]) + end + end + class BugTriaged < Activity end @@ -65,6 +71,7 @@ class BountySuggested < Activity 'activity-bounty-awarded' => BountyAwarded, 'activity-swag-awarded' => SwagAwarded, 'activity-user-assigned-to-bug' => UserAssignedToBug, + 'activity-group-assigned-to-bug' => GroupAssignedToBug, 'activity-bug-triaged' => BugTriaged, 'activity-reference-id-added' => ReferenceIdAdded, 'activity-comment' => CommentAdded, diff --git a/lib/hackerone/client/incremental/activities.rb b/lib/hackerone/client/incremental/activities.rb index c8f4d7b..9a7888a 100644 --- a/lib/hackerone/client/incremental/activities.rb +++ b/lib/hackerone/client/incremental/activities.rb @@ -31,12 +31,13 @@ def activities def next_page return nil unless next_cursor.present? - # Remove memoization - @current_page = nil - # Set cursor to next page @updated_at_after = next_cursor + # Remove memoization + @current_page = nil + @activities = nil + # Fetch new page current_page diff --git a/spec/hackerone/client/program_spec.rb b/spec/hackerone/client/program_spec.rb index c1b5a02..4fcee87 100644 --- a/spec/hackerone/client/program_spec.rb +++ b/spec/hackerone/client/program_spec.rb @@ -30,4 +30,49 @@ ).to be_present end end + + describe '.incremental_activities' do + it 'can traverse through the activities of a program' do + incremental_activities = program.incremental_activities(updated_at_after: DateTime.new(2017, 12, 4, 15, 38), page_size: 3) + + activities = [] + VCR.use_cassette(:traverse_through_3_activities) do + incremental_activities.traverse do |activity| + activities << activity + end + end + + expect(activities.size).to eq 3 + group_assigned_to_bug, comment_added, bounty_awarded = activities + expect(group_assigned_to_bug) + .to be_a HackerOne::Client::Activities::GroupAssignedToBug + expect(group_assigned_to_bug.group).to be_present + expect(group_assigned_to_bug.group.name).to eq 'Standard' + expect(comment_added) + .to be_a HackerOne::Client::Activities::CommentAdded + expect(comment_added.message).to eq 'this is a comment' + expect(bounty_awarded) + .to be_a HackerOne::Client::Activities::BountyAwarded + expect(bounty_awarded.message).to eq "Here's a bounty!" + end + + it 'can traverse through all activities of a program' do + incremental_activities = program.incremental_activities + + activities = [] + VCR.use_cassette(:traverse_through_all_activities) do + incremental_activities.traverse do |activity| + activities << activity + end + end + + expect(activities.size).to eq 27 + + # Assert no activity appears twice + name_and_updated_at = activities.map do |activity| + "#{activity.class} #{activity.updated_at}" + end + expect(name_and_updated_at.size).to eq name_and_updated_at.uniq.size + end + end end