pubhubs/servers/phc/
hub.rs1use std::rc::Rc;
3
4use actix_web::web;
5
6use crate::api::ApiResultExt as _;
7use crate::api::OpenError;
8use crate::api::{self, NoPayload};
9
10use super::server::*;
11use api::phc::hub::*;
12
13impl App {
14 pub(super) async fn handle_hub_ticket(
15 app: Rc<Self>,
16 signed_req: web::Json<api::Signed<TicketReq>>,
17 ) -> api::Result<TicketResp> {
18 let signed_req = signed_req.into_inner();
19
20 let req = signed_req
21 .clone()
22 .open_without_checking_signature()
23 .map_err(|oe| {
24 log::debug!("received invalid ticket request: {oe}");
25
26 match oe {
27 OpenError::OtherConstellation(..)
28 | OpenError::InternalError
29 | OpenError::InvalidSignature => api::ErrorCode::InternalError,
30 OpenError::OtherwiseInvalid | OpenError::Expired => api::ErrorCode::BadRequest,
31 }
32 })?;
33
34 let Some(hub) = app.shared.hubs.get(&req.handle) else {
35 return Ok(TicketResp::UnknownHub);
36 };
37
38 let resp = app
39 .client
40 .query::<api::hub::InfoEP>(&hub.url, NoPayload)
41 .await
42 .into_server_result()?;
43
44 let Some(verifying_key) = resp.verifying_key else {
45 return Ok(TicketResp::NoVerifyingKey);
46 };
47
48 let Ok(hub_verifying_key) = verifying_key.decode() else {
49 log::warn!("hub {} returned a malformed verifying key", req.handle);
50 return Err(api::ErrorCode::BadRequest);
51 };
52
53 signed_req.open(&hub_verifying_key, None).map_err(|oe| {
55 log::warn!(
56 "could not verify authenticity of hub ticket request for hub {}: {oe}",
57 req.handle,
58 );
59
60 match oe {
61 OpenError::OtherConstellation(..) | OpenError::InternalError => {
62 api::ErrorCode::InternalError
63 }
64 OpenError::OtherwiseInvalid | OpenError::Expired | OpenError::InvalidSignature => {
65 api::ErrorCode::BadRequest
66 }
67 }
68 })?;
69
70 Ok(TicketResp::Success(api::Signed::new(
72 &app.shared.signing_key,
73 &TicketContent {
74 handle: req.handle,
75 verifying_key,
76 },
77 std::time::Duration::from_secs(3600 * 24), )?))
79 }
80
81 pub(super) async fn handle_hub_ping(
83 app: Rc<Self>,
84 signed_req: web::Json<TicketSigned<api::server::PingReq>>,
85 ) -> api::Result<api::server::PingResp> {
86 crate::servers::AppBase::<Server>::handle_hub_ping(app, signed_req).await
87 }
88}