1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//! # hackerone-api
//!
//! Unofficial, dependency-light Rust client for the [HackerOne API][api] (v1).
//!
//! Built for the boring, reliable half of bug-bounty tooling: sign in, browse
//! your programs and their scopes, read your reports, **submit** a report,
//! search hacktivity, and read your balance and earnings — with HTTP Basic
//! auth and no async runtime.
//!
//! ## Hacker surface
//!
//! Report *submission* is a **hacker** operation. It lives under
//! `/v1/hackers/…`, not the customer `/v1/reports` surface. These endpoints
//! work with a researcher's API token:
//!
//! | Method | Endpoint |
//! |---|---|
//! | [`Client::create_report`] | `POST /v1/hackers/reports` |
//! | [`Client::my_reports`] | `GET /v1/hackers/me/reports` |
//! | [`Client::my_report`] | `GET /v1/hackers/reports/{id}` |
//! | [`Client::hacktivity`] | `GET /v1/hackers/hacktivity` |
//! | [`Client::balance`] | `GET /v1/hackers/payments/balance` |
//! | [`Client::earnings`] | `GET /v1/hackers/payments/earnings` |
//!
//! ## Customer surface
//!
//! [`Client::me`], [`Client::programs`], [`Client::program`],
//! [`Client::structured_scopes`], [`Client::reports`], [`Client::report`],
//! [`Client::add_comment`], [`Client::change_state`] and
//! [`Client::weaknesses`] are the **customer/program** API. A hacker-only API
//! token receives `401` on those routes (they require program access), even
//! though the token is valid.
//!
//! ## Submit a report
//!
//! ```no_run
//! use hackerone_api::{Client, CreateHackerReport, SeverityRating};
//!
//! fn main() -> Result<(), hackerone_api::Error> {
//! let client = Client::new("api-identifier", "api-token");
//!
//! let report = CreateHackerReport::new("sec", "Stored XSS in the profile page")
//! .vulnerability_information("## Steps\n1. …")
//! .impact("Session theft for any user who views the profile.")
//! .severity(SeverityRating::High)
//! .weakness_id(1337)
//! .structured_scope_id(57);
//!
//! let created = client.create_report(&report)?;
//! println!("filed: {} [{}]", created.title.unwrap_or_default(), created.state.unwrap_or_default());
//! Ok(())
//! }
//! ```
//!
//! The created report's numeric id is returned on the response envelope's
//! `data.id`; [`Client::create_report`] returns the report attributes
//! ([`Report`]), matching [`Client::report`]. To read ids for existing
//! reports, use [`Client::my_reports`] and [`Page::ids`].
//!
//! ## Auth
//!
//! The API uses HTTP Basic auth: the *username* is your API token
//! **identifier** and the *password* is the token **value**. Create one in
//! your HackerOne account settings. The examples read them from the
//! `HACKERONE_API_IDENTIFIER` / `HACKERONE_API_TOKEN` environment variables.
//!
//! ## Design
//!
//! - **Blocking, no async runtime.** [`ureq`] under the hood.
//! - **Injectable transport.** The client is generic over [`Transport`], so
//! tests use a mock and embedders can swap the HTTP stack.
//! - **Forward-compatible types.** Domain structs keep the documented fields
//! and stash unknown ones in a flattened `extra` map.
//!
//! ## Disclaimer
//!
//! This crate is unofficial and not affiliated with or endorsed by
//! HackerOne. "HackerOne" is a trademark of its owner; the name is used only
//! to describe what the library talks to.
//!
//! [api]: https://api.hackerone.com/
pub use ;
pub use ;
pub use ;
pub use ;