62 lines
1.7 KiB
Rust
62 lines
1.7 KiB
Rust
use std::{env, fs};
|
|
|
|
use axum::{extract, http::HeaderMap};
|
|
use chrono::{Duration, Utc};
|
|
use common::Adaptor;
|
|
use tracing::info;
|
|
|
|
use crate::{errors::ApiError, State};
|
|
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/tasks/cleanup",
|
|
responses(
|
|
(status = 200, description = "Cleanup complete"),
|
|
(status = 401, description = "Missing or incorrect X-Cron-Key header"),
|
|
(status = 429, description = "Too many requests"),
|
|
),
|
|
security((), ("cron-key" = [])),
|
|
tag = "tasks",
|
|
)]
|
|
/// Delete events older than 3 months
|
|
pub async fn cleanup<A: Adaptor>(
|
|
extract::State(state): State<A>,
|
|
headers: HeaderMap,
|
|
) -> Result<(), ApiError<A>> {
|
|
// Check cron key
|
|
let cron_key_header: String = headers
|
|
.get("X-Cron-Key")
|
|
.map(|k| k.to_str().unwrap_or_default().into())
|
|
.unwrap_or_default();
|
|
let env_key = if let Ok(key) = env::var("CRON_KEY") {
|
|
key
|
|
} else if let Some(path) = env::var_os("CRON_KEY_FILE") {
|
|
let Ok(key) = fs::read(&path) else {
|
|
println!("Error reading CRON_KEY_FILE at {path:?}");
|
|
return Err(ApiError::NotAuthorized);
|
|
};
|
|
String::from_utf8_lossy(key.as_slice()).into()
|
|
} else {
|
|
Default::default()
|
|
};
|
|
if !env_key.is_empty() && cron_key_header != env_key {
|
|
return Err(ApiError::NotAuthorized);
|
|
}
|
|
|
|
info!("Running cleanup task");
|
|
|
|
let adaptor = &state.lock().await.adaptor;
|
|
|
|
let result = adaptor
|
|
.delete_events(Utc::now() - Duration::days(90))
|
|
.await
|
|
.map_err(ApiError::AdaptorError)?;
|
|
|
|
info!(
|
|
"Cleanup successful: {} events and {} people removed",
|
|
result.event_count, result.person_count
|
|
);
|
|
|
|
Ok(())
|
|
}
|