this repo has no description
1use crate::api::ApiError;
2use crate::state::AppState;
3use axum::{
4 extract::State,
5 http::StatusCode,
6 response::{IntoResponse, Response},
7 Json,
8};
9use chrono::{Duration, Utc};
10use serde_json::json;
11use tracing::{error, info, warn};
12fn generate_plc_token() -> String {
13 crate::util::generate_token_code()
14}
15pub async fn request_plc_operation_signature(
16 State(state): State<AppState>,
17 headers: axum::http::HeaderMap,
18) -> Response {
19 let token = match crate::auth::extract_bearer_token_from_header(
20 headers.get("Authorization").and_then(|h| h.to_str().ok()),
21 ) {
22 Some(t) => t,
23 None => return ApiError::AuthenticationRequired.into_response(),
24 };
25 let auth_user = match crate::auth::validate_bearer_token(&state.db, &token).await {
26 Ok(user) => user,
27 Err(e) => return ApiError::from(e).into_response(),
28 };
29 let user = match sqlx::query!("SELECT id FROM users WHERE did = $1", auth_user.did)
30 .fetch_optional(&state.db)
31 .await
32 {
33 Ok(Some(row)) => row,
34 Ok(None) => return ApiError::AccountNotFound.into_response(),
35 Err(e) => {
36 error!("DB error: {:?}", e);
37 return ApiError::InternalError.into_response();
38 }
39 };
40 let _ = sqlx::query!(
41 "DELETE FROM plc_operation_tokens WHERE user_id = $1 OR expires_at < NOW()",
42 user.id
43 )
44 .execute(&state.db)
45 .await;
46 let plc_token = generate_plc_token();
47 let expires_at = Utc::now() + Duration::minutes(10);
48 if let Err(e) = sqlx::query!(
49 r#"
50 INSERT INTO plc_operation_tokens (user_id, token, expires_at)
51 VALUES ($1, $2, $3)
52 "#,
53 user.id,
54 plc_token,
55 expires_at
56 )
57 .execute(&state.db)
58 .await
59 {
60 error!("Failed to create PLC token: {:?}", e);
61 return (
62 StatusCode::INTERNAL_SERVER_ERROR,
63 Json(json!({"error": "InternalError"})),
64 )
65 .into_response();
66 }
67 let hostname = std::env::var("PDS_HOSTNAME").unwrap_or_else(|_| "localhost".to_string());
68 if let Err(e) = crate::notifications::enqueue_plc_operation(
69 &state.db,
70 user.id,
71 &plc_token,
72 &hostname,
73 )
74 .await
75 {
76 warn!("Failed to enqueue PLC operation notification: {:?}", e);
77 }
78 info!("PLC operation signature requested for user {}", auth_user.did);
79 (StatusCode::OK, Json(json!({}))).into_response()
80}