alopex_server/http/
session.rs1use std::sync::Arc;
2
3use axum::extract::{Extension, Path};
4use axum::response::Response;
5use serde::Serialize;
6
7use crate::error::{Result, ServerError};
8use crate::http::{error_response, json_response, RequestContext};
9use crate::server::ServerState;
10use crate::session::SessionId;
11
12#[derive(Serialize)]
13struct SessionBeginResponse {
14 session_id: String,
15 expires_at: String,
16}
17
18#[derive(Serialize)]
19struct SessionActionResponse {
20 success: bool,
21}
22
23pub async fn begin(
24 Extension(state): Extension<Arc<ServerState>>,
25 Extension(ctx): Extension<RequestContext>,
26) -> Response {
27 match begin_session(state.clone()).await {
28 Ok(resp) => json_response(resp, state.config.max_response_size, &ctx),
29 Err(err) => error_response(err, &ctx),
30 }
31}
32
33pub async fn commit(
34 Extension(state): Extension<Arc<ServerState>>,
35 Extension(ctx): Extension<RequestContext>,
36 Path(id): Path<String>,
37) -> Response {
38 match session_action(state.clone(), &id, Action::Commit).await {
39 Ok(resp) => json_response(resp, state.config.max_response_size, &ctx),
40 Err(err) => error_response(err, &ctx),
41 }
42}
43
44pub async fn rollback(
45 Extension(state): Extension<Arc<ServerState>>,
46 Extension(ctx): Extension<RequestContext>,
47 Path(id): Path<String>,
48) -> Response {
49 match session_action(state.clone(), &id, Action::Rollback).await {
50 Ok(resp) => json_response(resp, state.config.max_response_size, &ctx),
51 Err(err) => error_response(err, &ctx),
52 }
53}
54
55async fn begin_session(state: Arc<ServerState>) -> Result<SessionBeginResponse> {
56 let session_id = state.session_manager.create_session().await?;
57 state.session_manager.begin_transaction(&session_id).await?;
58 let snapshot = state.session_manager.get_session(&session_id).await?;
59 let expires_at = chrono::DateTime::<chrono::Utc>::from(snapshot.expires_at);
60 Ok(SessionBeginResponse {
61 session_id: session_id.to_string(),
62 expires_at: expires_at.to_rfc3339(),
63 })
64}
65
66enum Action {
67 Commit,
68 Rollback,
69}
70
71async fn session_action(
72 state: Arc<ServerState>,
73 id: &str,
74 action: Action,
75) -> Result<SessionActionResponse> {
76 let session_id = id
77 .parse::<SessionId>()
78 .map_err(|_| ServerError::BadRequest("invalid session id".into()))?;
79 match action {
80 Action::Commit => state.session_manager.commit(&session_id).await?,
81 Action::Rollback => state.session_manager.rollback(&session_id).await?,
82 }
83 Ok(SessionActionResponse { success: true })
84}