spamhaus_submission/lib.rs
1//! An async client for the [Spamhaus Submission Portal API].
2//!
3//! The Submission Portal lets you report malicious IP addresses, domains, URLs and
4//! emails to Spamhaus, and read back what their review found.
5//!
6//! # Get a token
7//!
8//! Go to <https://auth.spamhaus.org/account>, find "API Key Creation" and click
9//! "Create Key". Spamhaus shows the key one time only, so copy it then.
10//!
11//! # Send a report
12//!
13//! ```no_run
14//! use spamhaus_submission::{ApiToken, Client, Outcome, Reason, ThreatTypeCode};
15//!
16//! # async fn run() -> Result<(), spamhaus_submission::Error> {
17//! let client = Client::new(ApiToken::new(std::env::var("SPAMHAUS_TOKEN").unwrap())?)?;
18//!
19//! let outcome = client
20//! .submit_ip(
21//! ThreatTypeCode::new("spam")?,
22//! Reason::new("found on a forum")?,
23//! "221.22.34.2".parse().unwrap(),
24//! )
25//! .await?;
26//!
27//! match outcome {
28//! Outcome::Accepted(accepted) => println!("stored as {}", accepted.id.as_str()),
29//! Outcome::AlreadyReported => println!("Spamhaus already holds this one"),
30//! }
31//! # Ok(())
32//! # }
33//! ```
34//!
35//! # Read your history
36//!
37//! ```no_run
38//! use spamhaus_submission::{ApiToken, Client, ListParams, Status};
39//!
40//! # async fn run() -> Result<(), spamhaus_submission::Error> {
41//! let client = Client::new(ApiToken::new("token")?)?;
42//!
43//! for record in client.list_all(ListParams::default()).await? {
44//! match record.status {
45//! Status::Pending => println!("{}: not reviewed yet", record.object),
46//! Status::Clear { .. } => println!("{}: in no dataset", record.object),
47//! Status::Listed { datasets, .. } => {
48//! let names: Vec<_> = datasets.iter().map(|d| d.as_str()).collect();
49//! println!("{}: listed in {}", record.object, names.join(", "));
50//! }
51//! }
52//! }
53//! # Ok(())
54//! # }
55//! ```
56//!
57//! # Design
58//!
59//! Values you send are checked when you build them, so a request that Spamhaus is
60//! certain to reject never leaves the process. Values Spamhaus sends back are not
61//! checked the same way: a change on their side must not turn a working call into a
62//! parse failure.
63//!
64//! [Spamhaus Submission Portal API]: https://submit.spamhaus.org/api/
65
66#![forbid(unsafe_code)]
67
68mod client;
69mod error;
70mod report;
71mod submission;
72mod threat;
73mod token;
74
75pub use client::{Client, ClientBuilder, DEFAULT_BASE_URL};
76pub use error::{Error, ValidationError};
77pub use report::{Domain, RawEmail, Reason, Report, Target, ThreatTypeCode, UrlTarget};
78pub use submission::{
79 Accepted, Attributes, Counts, Dataset, ListParams, Outcome, Record, Status, SubmissionId,
80 SubmissionKind,
81};
82pub use threat::{ThreatScope, ThreatType};
83pub use token::ApiToken;