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