Files
continuwuity/src/core/matrix/pdu/unsigned.rs
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

89 lines
2.5 KiB
Rust
Raw Normal View History

use std::{borrow::Borrow, collections::BTreeMap};
2024-10-25 01:16:01 +00:00
use ruma::MilliSecondsSinceUnixEpoch;
use serde_json::value::{RawValue as RawJsonValue, Value as JsonValue, to_raw_value};
2024-10-25 01:16:01 +00:00
2024-11-07 03:30:47 +00:00
use super::Pdu;
use crate::{Result, err, implement, result::LogErr};
/// Set the `unsigned` field of the PDU using only information in the PDU.
/// Some unsigned data is already set within the database (eg. prev events,
/// threads). Once this is done, other data must be calculated from the database
/// (eg. relations) This is for server-to-client events.
/// Backfill handles this itself.
#[implement(Pdu)]
pub fn set_unsigned(&mut self, user_id: Option<&ruma::UserId>) {
if Some(self.sender.borrow()) != user_id {
self.remove_transaction_id().log_err().ok();
}
self.add_age().log_err().ok();
}
2024-10-25 01:16:01 +00:00
2024-11-07 03:30:47 +00:00
#[implement(Pdu)]
pub fn remove_transaction_id(&mut self) -> Result {
2025-02-06 10:23:17 +00:00
use BTreeMap as Map;
2024-10-25 01:16:01 +00:00
let Some(unsigned) = &self.unsigned else {
return Ok(());
};
2025-02-06 10:23:17 +00:00
let mut unsigned: Map<&str, Box<RawJsonValue>> = serde_json::from_str(unsigned.get())
.map_err(|e| err!(Database("Invalid unsigned in pdu event: {e}")))?;
2024-10-25 01:16:01 +00:00
unsigned.remove("transaction_id");
self.unsigned = to_raw_value(&unsigned)
.map(Some)
.expect("unsigned is valid");
Ok(())
}
2024-11-07 03:30:47 +00:00
#[implement(Pdu)]
pub fn add_age(&mut self) -> Result {
2025-02-06 10:23:17 +00:00
use BTreeMap as Map;
let mut unsigned: Map<&str, Box<RawJsonValue>> = self
2024-10-25 01:16:01 +00:00
.unsigned
2025-02-06 10:23:17 +00:00
.as_deref()
.map(RawJsonValue::get)
.map_or_else(|| Ok(Map::new()), serde_json::from_str)
2024-10-25 01:16:01 +00:00
.map_err(|e| err!(Database("Invalid unsigned in pdu event: {e}")))?;
// deliberately allowing for the possibility of negative age
let now: i128 = MilliSecondsSinceUnixEpoch::now().get().into();
let then: i128 = self.origin_server_ts.into();
let this_age = now.saturating_sub(then);
2025-02-06 10:23:17 +00:00
unsigned.insert("age", to_raw_value(&this_age)?);
self.unsigned = Some(to_raw_value(&unsigned)?);
2024-10-25 01:16:01 +00:00
Ok(())
}
2024-11-07 03:30:47 +00:00
#[implement(Pdu)]
2025-02-06 09:53:53 +00:00
pub fn add_relation(&mut self, name: &str, pdu: Option<&Pdu>) -> Result {
use serde_json::Map;
let mut unsigned: Map<String, JsonValue> = self
2024-11-07 03:30:47 +00:00
.unsigned
2025-02-06 10:23:17 +00:00
.as_deref()
.map(RawJsonValue::get)
.map_or_else(|| Ok(Map::new()), serde_json::from_str)
2024-11-07 03:30:47 +00:00
.map_err(|e| err!(Database("Invalid unsigned in pdu event: {e}")))?;
2025-02-06 09:53:53 +00:00
let pdu = pdu
.map(serde_json::to_value)
.transpose()?
.unwrap_or_else(|| JsonValue::Object(Map::new()));
2024-11-07 03:30:47 +00:00
2025-02-06 09:53:53 +00:00
unsigned
.entry("m.relations")
.or_insert(JsonValue::Object(Map::new()))
2024-11-07 03:30:47 +00:00
.as_object_mut()
2025-02-06 10:23:17 +00:00
.map(|object| object.insert(name.to_owned(), pdu));
2024-11-07 03:30:47 +00:00
2025-02-06 10:23:17 +00:00
self.unsigned = Some(to_raw_value(&unsigned)?);
2024-11-07 03:30:47 +00:00
Ok(())
}