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