add a log for each person accessing the chat api

This commit is contained in:
Marcel Märtens 2023-10-18 13:05:22 +02:00
parent 0baab58928
commit 9e5bd1e463
3 changed files with 35 additions and 4 deletions

View File

@ -60,7 +60,7 @@ where
"veloren_server::events::entity_manipulation=info",
"hyper=info",
"prometheus_hyper=info",
"mio::pool=info",
"mio::poll=info",
"mio::sys::windows=info",
"h2=info",
"tokio_util=info",

View File

@ -1,5 +1,5 @@
use axum::{
extract::{Query, State},
extract::{ConnectInfo, Query, State},
middleware::Next,
response::{IntoResponse, Response},
routing::get,
@ -9,7 +9,13 @@ use chrono::DateTime;
use hyper::{Request, StatusCode};
use serde::{Deserialize, Deserializer};
use server::chat::ChatCache;
use std::str::FromStr;
use std::{
collections::HashSet,
net::{IpAddr, SocketAddr},
str::FromStr,
sync::Arc,
};
use tokio::sync::Mutex;
/// Keep Size small, so we dont have to Clone much for each request.
#[derive(Clone)]
@ -17,6 +23,11 @@ struct ChatToken {
secret_token: Option<String>,
}
#[derive(Clone, Default)]
struct IpAddresses {
users: Arc<Mutex<HashSet<IpAddr>>>,
}
async fn validate_secret<B>(
State(token): State<ChatToken>,
req: Request<B>,
@ -38,10 +49,29 @@ async fn validate_secret<B>(
Ok(next.run(req).await)
}
/// Logs each new IP address that accesses this API authenticated
async fn log_users<B>(
State(ip_addresses): State<IpAddresses>,
ConnectInfo(addr): ConnectInfo<SocketAddr>,
req: Request<B>,
next: Next<B>,
) -> Result<Response, StatusCode> {
let mut ip_addresses = ip_addresses.users.lock().await;
let ip_addr = addr.ip();
if !ip_addresses.contains(&ip_addr) {
ip_addresses.insert(ip_addr);
let users_so_far = ip_addresses.len();
tracing::info!(?ip_addr, ?users_so_far, "Is accessing the /chat endpoint");
}
Ok(next.run(req).await)
}
pub fn router(cache: ChatCache, secret_token: Option<String>) -> Router {
let token = ChatToken { secret_token };
let ip_addrs = IpAddresses::default();
Router::new()
.route("/history", get(history))
.layer(axum::middleware::from_fn_with_state(ip_addrs, log_users))
.layer(axum::middleware::from_fn_with_state(token, validate_secret))
.with_state(cache)
}

View File

@ -30,7 +30,8 @@ where
// run it
let addr = addr.into();
let server = axum::Server::bind(&addr).serve(app.into_make_service());
let server =
axum::Server::bind(&addr).serve(app.into_make_service_with_connect_info::<SocketAddr>());
let server = server.with_graceful_shutdown(shutdown);
tracing::info!("listening on {}", addr);
match server.await {