subscan/modules/integrations/
bufferover.rs1use std::collections::BTreeSet;
2
3use regex::Match;
4use reqwest::Url;
5use serde_json::Value;
6
7use crate::{
8 enums::{
9 auth::AuthenticationMethod,
10 content::Content,
11 dispatchers::{RequesterDispatcher, SubscanModuleDispatcher},
12 },
13 error::ModuleErrorKind::JSONExtract,
14 extractors::json::JSONExtractor,
15 modules::generics::integration::GenericIntegrationModule,
16 requesters::client::HTTPClient,
17 types::{
18 core::{Result, Subdomain, SubscanModuleCoreComponents},
19 func::GenericIntegrationCoreFuncs,
20 },
21 utilities::regex::generate_subdomain_regex,
22};
23
24pub const BUFFEROVER_MODULE_NAME: &str = "bufferover";
25pub const BUFFEROVER_URL: &str = "https://tls.bufferover.run";
26
27pub struct BufferOver {}
41
42impl BufferOver {
43 pub fn dispatcher() -> SubscanModuleDispatcher {
44 let requester: RequesterDispatcher = HTTPClient::default().into();
45 let extractor: JSONExtractor = JSONExtractor::new(Box::new(Self::extract));
46
47 let generic = GenericIntegrationModule {
48 name: BUFFEROVER_MODULE_NAME.into(),
49 auth: AuthenticationMethod::APIKeyAsHeader("X-API-Key".into()),
50 funcs: GenericIntegrationCoreFuncs {
51 url: Box::new(Self::get_query_url),
52 next: Box::new(Self::get_next_url),
53 },
54 components: SubscanModuleCoreComponents {
55 requester: requester.into(),
56 extractor: extractor.into(),
57 },
58 };
59
60 generic.into()
61 }
62
63 pub fn get_query_url(domain: &str) -> String {
64 format!("{BUFFEROVER_URL}/dns?q={domain}")
65 }
66
67 pub fn get_next_url(_url: Url, _content: Content) -> Option<Url> {
68 None
69 }
70
71 pub fn extract(content: Value, domain: &str) -> Result<BTreeSet<Subdomain>> {
72 if let Some(results) = content["Results"].as_array() {
73 let pattern = generate_subdomain_regex(domain)?;
74 let filter = |item: &Value| {
75 let to_string = |matches: Match| matches.as_str().to_string();
76
77 pattern.find(item.as_str()?).map(to_string)
78 };
79
80 return Ok(results.iter().filter_map(filter).collect());
81 }
82
83 Err(JSONExtract.into())
84 }
85}