this repo has no description
1use crate::api::ApiError; 2use crate::state::AppState; 3use axum::{ 4 Json, 5 extract::State, 6 http::StatusCode, 7 response::{IntoResponse, Response}, 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 let auth_user = match crate::auth::validate_bearer_token_allow_deactivated(&state.db, &token).await { 28 Ok(user) => user, 29 Err(e) => return ApiError::from(e).into_response(), 30 }; 31 let user = match sqlx::query!("SELECT id FROM users WHERE did = $1", auth_user.did) 32 .fetch_optional(&state.db) 33 .await 34 { 35 Ok(Some(row)) => row, 36 Ok(None) => return ApiError::AccountNotFound.into_response(), 37 Err(e) => { 38 error!("DB error: {:?}", e); 39 return ApiError::InternalError.into_response(); 40 } 41 }; 42 let _ = sqlx::query!( 43 "DELETE FROM plc_operation_tokens WHERE user_id = $1 OR expires_at < NOW()", 44 user.id 45 ) 46 .execute(&state.db) 47 .await; 48 let plc_token = generate_plc_token(); 49 let expires_at = Utc::now() + Duration::minutes(10); 50 if let Err(e) = sqlx::query!( 51 r#" 52 INSERT INTO plc_operation_tokens (user_id, token, expires_at) 53 VALUES ($1, $2, $3) 54 "#, 55 user.id, 56 plc_token, 57 expires_at 58 ) 59 .execute(&state.db) 60 .await 61 { 62 error!("Failed to create PLC token: {:?}", e); 63 return ( 64 StatusCode::INTERNAL_SERVER_ERROR, 65 Json(json!({"error": "InternalError"})), 66 ) 67 .into_response(); 68 } 69 let hostname = std::env::var("PDS_HOSTNAME").unwrap_or_else(|_| "localhost".to_string()); 70 if let Err(e) = 71 crate::comms::enqueue_plc_operation(&state.db, user.id, &plc_token, &hostname).await 72 { 73 warn!("Failed to enqueue PLC operation notification: {:?}", e); 74 } 75 info!( 76 "PLC operation signature requested for user {}", 77 auth_user.did 78 ); 79 (StatusCode::OK, Json(json!({}))).into_response() 80}