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