heldar_kernel/routes/
playback_sessions.rs1use axum::extract::{Path, State};
9use axum::http::StatusCode;
10use axum::routing::post;
11use axum::{Json, Router};
12use serde::Deserialize;
13use serde_json::json;
14
15use crate::auth::{self, Principal};
16use crate::error::{AppError, AppResult};
17use crate::services::playback_session::{self, PlaybackSession};
18use crate::state::AppState;
19use crate::util;
20
21pub fn router() -> Router<AppState> {
22 Router::new()
23 .route(
24 "/api/v1/cameras/{id}/playback/sessions",
25 post(create_session),
26 )
27 .route(
28 "/api/v1/playback/sessions/{session_id}",
29 axum::routing::delete(delete_session),
30 )
31}
32
33#[derive(Debug, Deserialize)]
34struct CreateSessionRequest {
35 from: String,
36 to: String,
37}
38
39async fn create_session(
40 State(st): State<AppState>,
41 Path(id): Path<String>,
42 principal: Principal,
43 Json(req): Json<CreateSessionRequest>,
44) -> AppResult<Json<PlaybackSession>> {
45 principal.require(principal.can_view(), "create playback sessions")?;
47 let from = util::parse_rfc3339(&req.from)
48 .ok_or_else(|| AppError::BadRequest("invalid `from` timestamp".into()))?;
49 let to = util::parse_rfc3339(&req.to)
50 .ok_or_else(|| AppError::BadRequest("invalid `to` timestamp".into()))?;
51 let session = playback_session::create_session(&st, &id, from, to).await?;
52 auth::audit(
53 &st.pool,
54 &principal,
55 "create_playback_session",
56 "camera",
57 &id,
58 json!({ "session_id": session.id, "from": from, "to": to }),
59 )
60 .await;
61 Ok(Json(session))
62}
63
64async fn delete_session(
65 State(st): State<AppState>,
66 Path(session_id): Path<String>,
67 principal: Principal,
68) -> AppResult<StatusCode> {
69 principal.require(principal.can_view(), "delete playback sessions")?;
71 playback_session::delete_session(&st, &session_id).await?;
72 auth::audit(
73 &st.pool,
74 &principal,
75 "delete_playback_session",
76 "playback_session",
77 &session_id,
78 json!({}),
79 )
80 .await;
81 Ok(StatusCode::NO_CONTENT)
82}