tuwunel_api/client/admin/tokens/
update.rs1use std::time::{Duration, SystemTime};
2
3use axum::extract::State;
4use ruma::{JsOption, MilliSecondsSinceUnixEpoch, UInt};
5use synapse_admin_api::registration_tokens::update::v1 as update;
6use tuwunel_core::{Err, Result, utils::time::timepoint_from_epoch};
7use tuwunel_service::registration_tokens::{TokenExpires, TokenInfo};
8
9use super::database_token_response;
10use crate::{Ruma, client::admin::require_admin};
11
12pub(crate) async fn admin_update_token_route(
17 State(services): State<crate::State>,
18 body: Ruma<update::Request>,
19) -> Result<update::Response> {
20 require_admin(&services, body.sender_user()).await?;
21
22 let token = &body.token;
23
24 let info = services
25 .registration_tokens
26 .get_token_info(token)
27 .await?;
28
29 let info = match info {
30 | TokenInfo::Database(info) => info,
31 | TokenInfo::Config =>
32 return Err!(Request(Forbidden("Tokens set in the config file can't be updated"))),
33 };
34
35 let max_uses = apply_uses(body.uses_allowed, info.expires.max_uses);
36 let max_age = apply_age(body.expiry_time, info.expires.max_age)?;
37 let expires = TokenExpires { max_uses, max_age };
38
39 let info = services
40 .registration_tokens
41 .update_token(token, expires)
42 .await?;
43
44 Ok(update::Response {
45 token: database_token_response(token.clone(), &info),
46 })
47}
48
49fn apply_uses(uses_allowed: JsOption<UInt>, current: Option<u64>) -> Option<u64> {
52 match uses_allowed.into_nested_option() {
53 | None => current,
54 | Some(cap) => cap.map(Into::into),
55 }
56}
57
58fn apply_age(
61 expiry_time: JsOption<MilliSecondsSinceUnixEpoch>,
62 current: Option<SystemTime>,
63) -> Result<Option<SystemTime>> {
64 match expiry_time.into_nested_option() {
65 | None => Ok(current),
66 | Some(None) => Ok(None),
67 | Some(Some(ms)) => timepoint_from_epoch(Duration::from_millis(ms.0.into())).map(Some),
68 }
69}