pubhubs/servers/auths/
keys.rs1use super::server::*;
3
4use std::collections::HashMap;
5use std::rc::Rc;
6
7use actix_web::web;
8
9use crate::{
10 api::{self},
11 attr, handle, phcrypto,
12};
13
14impl App {
15 pub async fn handle_attr_keys(
17 app: Rc<Self>,
18 reqs: web::Json<HashMap<handle::Handle, api::auths::AttrKeyReq>>,
19 ) -> api::Result<api::auths::AttrKeysResp> {
20 let running_state = &app.running_state_or_please_retry()?;
21
22 let reqs = reqs.into_inner();
23
24 let mut resp: HashMap<handle::Handle, api::auths::AttrKeyResp> =
25 HashMap::with_capacity(reqs.len());
26
27 let now = api::NumericDate::now();
28
29 for (handle, req) in reqs.into_iter() {
30 let attr: attr::Attr = match req
31 .attr
32 .open(&running_state.attr_signing_key, None) {
34 Err(api::OpenError::OtherConstellation(..))
35 | Err(api::OpenError::InvalidSignature)
36 | Err(api::OpenError::Expired) => {
37 return Ok(api::auths::AttrKeysResp::RetryWithNewAttr(handle));
38 }
39 Err(api::OpenError::OtherwiseInvalid) => {
40 return Err(api::ErrorCode::BadRequest);
41 }
42 Err(api::OpenError::InternalError) => {
43 return Err(api::ErrorCode::InternalError);
44 }
45 Ok(attr) => attr
46 };
47
48 if attr.not_identifying {
49 log::debug!(
50 "attribute key denied for non-identifying attribute {value} of type {attr_type}",
51 value = attr.value,
52 attr_type = attr.attr_type
53 );
54 return Err(api::ErrorCode::BadRequest);
55 }
56
57 let timestamps: Vec<api::NumericDate> = if let Some(timestamp) = req.timestamp {
58 if timestamp > now {
59 log::warn!(
60 "future attribute key requested for attribute {value} of type {attr_type}",
61 value = attr.value,
62 attr_type = attr.attr_type
63 );
64 return Err(api::ErrorCode::BadRequest);
65 }
66
67 vec![timestamp, now]
68 } else {
69 vec![now]
70 };
71
72 let mut attr_keys: Vec<Vec<u8>> =
73 phcrypto::auths_attr_keys(attr, app.attr_key_secret.as_slice(), timestamps);
74
75 let latest_key: Vec<u8> = attr_keys.pop().unwrap();
76 let old_key: Option<Vec<u8>> = attr_keys.pop();
77
78 assert!(attr_keys.is_empty());
79
80 resp.insert(
81 handle.clone(),
82 api::auths::AttrKeyResp {
83 latest_key: (serde_bytes::ByteBuf::from(latest_key).into(), now),
84 old_key: old_key.map(|old_key| serde_bytes::ByteBuf::from(old_key).into()),
85 },
86 )
87 .map_or(Ok(()), |_| {
88 log::debug!("double handle in attribute keys request: {handle}");
89 Err(api::ErrorCode::BadRequest)
90 })?;
91 }
92
93 Ok(api::auths::AttrKeysResp::Success(resp))
94 }
95}