b69c2e1e94
* move stats types from vpn-client to here * base stats api * change storage schema * add link to nymAPI for whitelisting * remove outdated comment * more comments update * example of chrono vs time * Add build.rs - exports DATABASE_URL so cargo check works - exports SQLX_OFFLINE for CI - added pg_up.sh which spawns PG container - required for cargo sqlx prepare * fixes time vs chrono issue and cleaner build with docker * add correct swagger types, with feature locking where relevant * apply dynco suggestions --------- Co-authored-by: dynco-nym <173912580+dynco-nym@users.noreply.github.com>
64 lines
1.8 KiB
Rust
64 lines
1.8 KiB
Rust
use std::net::SocketAddr;
|
|
|
|
use axum::{
|
|
extract::{ConnectInfo, State},
|
|
Json, Router,
|
|
};
|
|
use axum_extra::{headers::UserAgent, TypedHeader};
|
|
use nym_statistics_common::report::vpn_client::VpnClientStatsReport;
|
|
use tracing::debug;
|
|
|
|
use crate::{
|
|
http::{
|
|
error::{HttpError, HttpResult},
|
|
state::AppState,
|
|
},
|
|
storage::models::{ConnectionInfoDto, DailyActiveDeviceDto},
|
|
};
|
|
|
|
pub(crate) fn routes() -> Router<AppState> {
|
|
Router::new().route("/report", axum::routing::post(submit_stats_report))
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
request_body = VpnClientStatsReport,
|
|
tag = "Stats",
|
|
path = "/report",
|
|
context_path = "/v1/stats",
|
|
responses(
|
|
(status = 200)
|
|
)
|
|
)]
|
|
#[tracing::instrument(level = "info", skip_all)]
|
|
async fn submit_stats_report(
|
|
State(mut state): State<AppState>,
|
|
ConnectInfo(addr): ConnectInfo<SocketAddr>,
|
|
TypedHeader(user_agent): TypedHeader<UserAgent>,
|
|
Json(report): Json<VpnClientStatsReport>,
|
|
) -> HttpResult<Json<()>> {
|
|
let now = time::OffsetDateTime::now_utc();
|
|
let gateway_record = state.network_view().get_country_by_ip(&addr.ip()).await;
|
|
|
|
let from_mixnet = gateway_record.is_some();
|
|
let maybe_location = gateway_record.unwrap_or_default();
|
|
|
|
if from_mixnet {
|
|
debug!("Received a report from the network");
|
|
} else {
|
|
debug!("Received a report from outside of the network");
|
|
}
|
|
|
|
let active_device = DailyActiveDeviceDto::new(now, &report, user_agent, from_mixnet);
|
|
let maybe_connection_info =
|
|
ConnectionInfoDto::maybe_new(now, &report, addr, maybe_location, from_mixnet);
|
|
|
|
state
|
|
.storage()
|
|
.store_vpn_client_report(active_device, maybe_connection_info)
|
|
.await
|
|
.map_err(HttpError::internal_with_logging)?;
|
|
|
|
Ok(Json(()))
|
|
}
|