autopulse_service/settings/targets/
autopulse.rs1use super::{Request, RequestBuilderPerform};
2use crate::settings::rewrite::Rewrite;
3use crate::settings::{auth::Auth, targets::TargetProcess};
4use autopulse_database::models::ScanEvent;
5use autopulse_utils::get_url;
6use reqwest::header;
7use serde::{Deserialize, Serialize};
8use tracing::{debug, error};
9
10#[derive(Serialize, Clone, Deserialize)]
11pub struct Autopulse {
12 pub url: String,
14 pub auth: Auth,
16 pub trigger: Option<String>,
18 pub rewrite: Option<Rewrite>,
20 #[serde(default)]
22 pub request: Request,
23}
24
25impl Autopulse {
26 fn get_client(&self) -> anyhow::Result<reqwest::Client> {
27 let mut headers = header::HeaderMap::new();
28
29 if self.auth.enabled {
30 headers.insert("Authorization", self.auth.to_auth_encoded().parse()?);
31 }
32
33 self.request
34 .client_builder(headers)
35 .build()
36 .map_err(Into::into)
37 }
38
39 async fn scan(&self, ev: &ScanEvent) -> anyhow::Result<()> {
40 let client = self.get_client()?;
41 let mut url = get_url(&self.url)?.join("triggers/manual")?;
42
43 url.query_pairs_mut()
44 .append_pair("path", &ev.get_path(&self.rewrite));
45
46 if let Some(hash) = &ev.file_hash {
47 url.query_pairs_mut().append_pair("hash", hash);
48 }
49
50 client.get(url).perform().await.map(|_| ())
51 }
52}
53
54impl TargetProcess for Autopulse {
55 async fn process(&self, evs: &[&ScanEvent]) -> anyhow::Result<Vec<String>> {
56 let mut succeeded = Vec::new();
57
58 for ev in evs {
59 match self.scan(ev).await {
60 Ok(()) => {
61 succeeded.push(ev.id.clone());
62 debug!("file scanned: {}", ev.get_path(&self.rewrite));
63 }
64 Err(e) => {
65 error!("error scanning file: {}", e);
66 }
67 }
68 }
69
70 Ok(succeeded)
71 }
72}