o_sfu/runtime/http_server/operator/
mod.rs1use std::net::SocketAddr;
4
5use axum::{
6 Router,
7 extract::{Request, State},
8 http::{HeaderValue, StatusCode, header},
9 middleware,
10 response::{IntoResponse, Response},
11 routing::get,
12};
13
14use super::{access::OperatorAccessPolicy, contract::route};
15use crate::runtime::RuntimeState;
16
17mod diagnostics;
18mod metrics;
19mod stats;
20
21pub(super) fn routes(state: &RuntimeState, listener_address: SocketAddr) -> Router<RuntimeState> {
27 let policy = OperatorAccessPolicy::new(
28 state.config.diagnostics.auth_token.as_ref(),
29 listener_address,
30 );
31 let authorization = middleware::map_request_with_state(policy, authorize_operator);
32 let observation_routes = Router::new()
33 .route(
34 route::v1::STATS,
35 get(stats::rooms).route_layer(authorization.clone()),
36 )
37 .route(
38 route::METRICS,
39 get(metrics::scrape).route_layer(authorization.clone()),
40 );
41 let diagnostics_routes = Router::new()
42 .route(route::diagnostics::SUMMARY, get(diagnostics::summary))
43 .route(route::diagnostics::ROOMS, get(diagnostics::rooms))
44 .route(route::diagnostics::WORKERS, get(diagnostics::workers))
45 .route(route::diagnostics::ROOM, get(diagnostics::room_detail))
46 .route(route::diagnostics::ROOM_USERS, get(diagnostics::room_users))
47 .route(route::diagnostics::ROOM_USER, get(diagnostics::user_detail))
48 .route_layer(authorization);
49 observation_routes.merge(diagnostics_routes)
50}
51
52async fn authorize_operator(
59 State(policy): State<OperatorAccessPolicy>,
60 request: Request,
61) -> Result<Request, Response> {
62 policy.authorize(request.headers()).map_err(|status| {
63 let mut response = status.into_response();
64 if status == StatusCode::UNAUTHORIZED {
65 response.headers_mut().insert(
66 header::WWW_AUTHENTICATE,
67 HeaderValue::from_static("Bearer realm=\"o-sfu\""),
68 );
69 }
70 response
71 })?;
72 Ok(request)
73}