use std::sync::Arc; use axum::http::HeaderMap; use export::AppState; use kenauth::KenAuthClient; use sha2::{Digest, Sha256}; use time::OffsetDateTime; use crate::errors::ApiError; pub fn client(state: &AppState) -> Result<&Arc, ApiError> { state .kenauth .as_ref() .ok_or_else(|| ApiError::internal("kenoauth client is not configured")) } pub fn client_ip(headers: &HeaderMap) -> String { headers .get("x-forwarded-for") .and_then(|value| value.to_str().ok()) .and_then(|value| value.split(',').next()) .map(str::trim) .filter(|value| !value.is_empty()) .or_else(|| { headers .get("x-real-ip") .and_then(|value| value.to_str().ok()) .map(str::trim) }) .unwrap_or_default() .to_string() } pub fn digest(password: &str) -> String { let hash = Sha256::digest(password.as_bytes()); let mut out = String::with_capacity(64); for byte in hash { out.push_str(&format!("{byte:02x}")); } out } pub fn datetime(seconds: i64, nanos: i32) -> Option { OffsetDateTime::from_unix_timestamp_nanos(i128::from(seconds) * 1_000_000_000 + i128::from(nanos)) .ok() }