cleanup some error callsites
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
parent
b903b46d16
commit
d67f19a55d
9 changed files with 96 additions and 144 deletions
|
@ -2,11 +2,8 @@ use std::{mem, ops::Deref};
|
||||||
|
|
||||||
use axum::{async_trait, body::Body, extract::FromRequest};
|
use axum::{async_trait, body::Body, extract::FromRequest};
|
||||||
use bytes::{BufMut, BytesMut};
|
use bytes::{BufMut, BytesMut};
|
||||||
use conduit::{debug, debug_warn, trace, warn, Error, Result};
|
use conduit::{debug, err, trace, Error, Result};
|
||||||
use ruma::{
|
use ruma::{api::IncomingRequest, CanonicalJsonValue, OwnedDeviceId, OwnedServerName, OwnedUserId, UserId};
|
||||||
api::{client::error::ErrorKind, IncomingRequest},
|
|
||||||
CanonicalJsonValue, OwnedDeviceId, OwnedServerName, OwnedUserId, UserId,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{auth, auth::Auth, request, request::Request};
|
use super::{auth, auth::Auth, request, request::Request};
|
||||||
use crate::{service::appservice::RegistrationInfo, services};
|
use crate::{service::appservice::RegistrationInfo, services};
|
||||||
|
@ -103,21 +100,14 @@ where
|
||||||
let mut http_request = hyper::Request::builder()
|
let mut http_request = hyper::Request::builder()
|
||||||
.uri(request.parts.uri.clone())
|
.uri(request.parts.uri.clone())
|
||||||
.method(request.parts.method.clone());
|
.method(request.parts.method.clone());
|
||||||
*http_request.headers_mut().unwrap() = request.parts.headers.clone();
|
*http_request.headers_mut().expect("mutable http headers") = request.parts.headers.clone();
|
||||||
let http_request = http_request.body(body).unwrap();
|
let http_request = http_request.body(body).expect("http request body");
|
||||||
debug!(
|
|
||||||
"{:?} {:?} {:?}",
|
|
||||||
http_request.method(),
|
|
||||||
http_request.uri(),
|
|
||||||
http_request.headers()
|
|
||||||
);
|
|
||||||
|
|
||||||
trace!("{:?} {:?} {:?}", http_request.method(), http_request.uri(), json_body);
|
let headers = http_request.headers();
|
||||||
let body = T::try_from_http_request(http_request, &request.path).map_err(|e| {
|
let method = http_request.method();
|
||||||
warn!("try_from_http_request failed: {e:?}",);
|
let uri = http_request.uri();
|
||||||
debug_warn!("JSON body: {:?}", json_body);
|
debug!("{method:?} {uri:?} {headers:?}");
|
||||||
Error::BadRequest(ErrorKind::BadJson, "Failed to deserialize request.")
|
trace!("{method:?} {uri:?} {json_body:?}");
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(body)
|
T::try_from_http_request(http_request, &request.path).map_err(|e| err!(Request(BadJson(debug_warn!("{e}")))))
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,11 @@ use std::str;
|
||||||
|
|
||||||
use axum::{extract::Path, RequestExt, RequestPartsExt};
|
use axum::{extract::Path, RequestExt, RequestPartsExt};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
use conduit::err;
|
||||||
use http::request::Parts;
|
use http::request::Parts;
|
||||||
use ruma::api::client::error::ErrorKind;
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::{services, Error, Result};
|
use crate::{services, Result};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub(super) struct QueryParams {
|
pub(super) struct QueryParams {
|
||||||
|
@ -26,14 +26,15 @@ pub(super) async fn from(request: hyper::Request<axum::body::Body>) -> Result<Re
|
||||||
let (mut parts, body) = limited.into_parts();
|
let (mut parts, body) = limited.into_parts();
|
||||||
|
|
||||||
let path: Path<Vec<String>> = parts.extract().await?;
|
let path: Path<Vec<String>> = parts.extract().await?;
|
||||||
let query = serde_html_form::from_str(parts.uri.query().unwrap_or_default())
|
let query = parts.uri.query().unwrap_or_default();
|
||||||
.map_err(|_| Error::BadRequest(ErrorKind::Unknown, "Failed to read query parameters"))?;
|
let query =
|
||||||
|
serde_html_form::from_str(query).map_err(|e| err!(Request(Unknown("Failed to read query parameters: {e}"))))?;
|
||||||
|
|
||||||
let max_body_size = services().globals.config.max_request_size;
|
let max_body_size = services().globals.config.max_request_size;
|
||||||
|
|
||||||
let body = axum::body::to_bytes(body, max_body_size)
|
let body = axum::body::to_bytes(body, max_body_size)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| Error::BadRequest(ErrorKind::TooLarge, "Request body too large"))?;
|
.map_err(|e| err!(Request(TooLarge("Request body too large: {e}"))))?;
|
||||||
|
|
||||||
Ok(Request {
|
Ok(Request {
|
||||||
path,
|
path,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{collections::BTreeMap, net::IpAddr, time::Instant};
|
use std::{collections::BTreeMap, net::IpAddr, time::Instant};
|
||||||
|
|
||||||
use axum_client_ip::InsecureClientIp;
|
use axum_client_ip::InsecureClientIp;
|
||||||
use conduit::debug_warn;
|
use conduit::{debug, debug_warn, err, trace, warn, Err};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::{
|
api::{
|
||||||
client::error::ErrorKind,
|
client::error::ErrorKind,
|
||||||
|
@ -18,7 +18,6 @@ use ruma::{
|
||||||
OwnedEventId, ServerName,
|
OwnedEventId, ServerName,
|
||||||
};
|
};
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
use tracing::{debug, error, trace, warn};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
service::rooms::event_handler::parse_incoming_pdu,
|
service::rooms::event_handler::parse_incoming_pdu,
|
||||||
|
@ -39,24 +38,17 @@ pub(crate) async fn send_transaction_message_route(
|
||||||
let origin = body.origin.as_ref().expect("server is authenticated");
|
let origin = body.origin.as_ref().expect("server is authenticated");
|
||||||
|
|
||||||
if *origin != body.body.origin {
|
if *origin != body.body.origin {
|
||||||
return Err(Error::BadRequest(
|
return Err!(Request(Forbidden(
|
||||||
ErrorKind::forbidden(),
|
"Not allowed to send transactions on behalf of other servers"
|
||||||
"Not allowed to send transactions on behalf of other servers",
|
)));
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if body.pdus.len() > 50_usize {
|
if body.pdus.len() > 50_usize {
|
||||||
return Err(Error::BadRequest(
|
return Err!(Request(Forbidden("Not allowed to send more than 50 PDUs in one transaction")));
|
||||||
ErrorKind::forbidden(),
|
|
||||||
"Not allowed to send more than 50 PDUs in one transaction",
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if body.edus.len() > 100_usize {
|
if body.edus.len() > 100_usize {
|
||||||
return Err(Error::BadRequest(
|
return Err!(Request(Forbidden("Not allowed to send more than 100 EDUs in one transaction")));
|
||||||
ErrorKind::forbidden(),
|
|
||||||
"Not allowed to send more than 100 EDUs in one transaction",
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let txn_start_time = Instant::now();
|
let txn_start_time = Instant::now();
|
||||||
|
@ -392,10 +384,9 @@ async fn handle_edu_direct_to_device(
|
||||||
target_user_id,
|
target_user_id,
|
||||||
target_device_id,
|
target_device_id,
|
||||||
&ev_type.to_string(),
|
&ev_type.to_string(),
|
||||||
event.deserialize_as().map_err(|e| {
|
event
|
||||||
error!("To-Device event is invalid: {event:?} {e}");
|
.deserialize_as()
|
||||||
Error::BadRequest(ErrorKind::InvalidParam, "Event is invalid")
|
.map_err(|e| err!(Request(InvalidParam(error!("To-Device event is invalid: {e}")))))?,
|
||||||
})?,
|
|
||||||
)?;
|
)?;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -408,7 +399,7 @@ async fn handle_edu_direct_to_device(
|
||||||
&ev_type.to_string(),
|
&ev_type.to_string(),
|
||||||
event
|
event
|
||||||
.deserialize_as()
|
.deserialize_as()
|
||||||
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Event is invalid"))?,
|
.map_err(|e| err!(Request(InvalidParam("Event is invalid: {e}"))))?,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
//! Err(Database(error!("problem with db: {msg}")))` logs the error at the
|
//! Err(Database(error!("problem with db: {msg}")))` logs the error at the
|
||||||
//! callsite and then returns the error with the same string. Caller has the
|
//! callsite and then returns the error with the same string. Caller has the
|
||||||
//! option of replacing `error!` with `debug_error!`.
|
//! option of replacing `error!` with `debug_error!`.
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! Err {
|
macro_rules! Err {
|
||||||
($($args:tt)*) => {
|
($($args:tt)*) => {
|
||||||
|
|
|
@ -78,7 +78,7 @@ pub enum Error {
|
||||||
|
|
||||||
// conduwuit
|
// conduwuit
|
||||||
#[error("Arithmetic operation failed: {0}")]
|
#[error("Arithmetic operation failed: {0}")]
|
||||||
Arithmetic(&'static str),
|
Arithmetic(Cow<'static, str>),
|
||||||
#[error("There was a problem with the '{0}' directive in your configuration: {1}")]
|
#[error("There was a problem with the '{0}' directive in your configuration: {1}")]
|
||||||
Config(&'static str, Cow<'static, str>),
|
Config(&'static str, Cow<'static, str>),
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
|
|
|
@ -2,14 +2,14 @@ use std::{cmp, time::Duration};
|
||||||
|
|
||||||
pub use checked_ops::checked_ops;
|
pub use checked_ops::checked_ops;
|
||||||
|
|
||||||
use crate::{Error, Result};
|
use crate::{Err, Error, Result};
|
||||||
|
|
||||||
/// Checked arithmetic expression. Returns a Result<R, Error::Arithmetic>
|
/// Checked arithmetic expression. Returns a Result<R, Error::Arithmetic>
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! checked {
|
macro_rules! checked {
|
||||||
($($input:tt)*) => {
|
($($input:tt)*) => {
|
||||||
$crate::utils::math::checked_ops!($($input)*)
|
$crate::utils::math::checked_ops!($($input)*)
|
||||||
.ok_or_else(|| $crate::Error::Arithmetic("operation overflowed or result invalid"))
|
.ok_or_else(|| $crate::err!(Arithmetic("operation overflowed or result invalid")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ macro_rules! validated {
|
||||||
($($input:tt)*) => {
|
($($input:tt)*) => {
|
||||||
//#[allow(clippy::arithmetic_side_effects)] {
|
//#[allow(clippy::arithmetic_side_effects)] {
|
||||||
//Some($($input)*)
|
//Some($($input)*)
|
||||||
// .ok_or_else(|| $crate::Error::Arithmetic("this error should never been seen"))
|
// .ok_or_else(|| $crate::err!(Arithmetic("this error should never been seen")))
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//NOTE: remove me when stmt_expr_attributes is stable
|
//NOTE: remove me when stmt_expr_attributes is stable
|
||||||
|
@ -57,7 +57,7 @@ pub fn continue_exponential_backoff(min: Duration, max: Duration, elapsed: Durat
|
||||||
#[allow(clippy::as_conversions)]
|
#[allow(clippy::as_conversions)]
|
||||||
pub fn usize_from_f64(val: f64) -> Result<usize, Error> {
|
pub fn usize_from_f64(val: f64) -> Result<usize, Error> {
|
||||||
if val < 0.0 {
|
if val < 0.0 {
|
||||||
return Err(Error::Arithmetic("Converting negative float to unsigned integer"));
|
return Err!(Arithmetic("Converting negative float to unsigned integer"));
|
||||||
}
|
}
|
||||||
|
|
||||||
//SAFETY: <https://doc.rust-lang.org/std/primitive.f64.html#method.to_int_unchecked>
|
//SAFETY: <https://doc.rust-lang.org/std/primitive.f64.html#method.to_int_unchecked>
|
||||||
|
|
|
@ -9,7 +9,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use conduit::{debug, error, Error, Result};
|
use conduit::{debug, error, error::default_log, Error, Result};
|
||||||
pub use create::create_admin_room;
|
pub use create::create_admin_room;
|
||||||
pub use grant::make_user_admin;
|
pub use grant::make_user_admin;
|
||||||
use loole::{Receiver, Sender};
|
use loole::{Receiver, Sender};
|
||||||
|
@ -239,9 +239,9 @@ async fn respond_to_room(content: RoomMessageEventContent, room_id: &RoomId, use
|
||||||
.build_and_append_pdu(response_pdu, user_id, room_id, &state_lock)
|
.build_and_append_pdu(response_pdu, user_id, room_id, &state_lock)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
if let Err(e) = handle_response_error(e, room_id, user_id, &state_lock).await {
|
handle_response_error(e, room_id, user_id, &state_lock)
|
||||||
error!("{e}");
|
.await
|
||||||
}
|
.unwrap_or_else(default_log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::{collections::HashMap, path::PathBuf, sync::Arc, time::SystemTime};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use base64::{engine::general_purpose, Engine as _};
|
use base64::{engine::general_purpose, Engine as _};
|
||||||
use conduit::{debug, debug_error, err, error, utils, Result, Server};
|
use conduit::{debug, debug_error, err, error, utils, Err, Result, Server};
|
||||||
use data::{Data, Metadata};
|
use data::{Data, Metadata};
|
||||||
use ruma::{OwnedMxcUri, OwnedUserId};
|
use ruma::{OwnedMxcUri, OwnedUserId};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
@ -100,10 +100,9 @@ impl Service {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
error!("Failed to find any media keys for MXC \"{mxc}\" in our database (MXC does not exist)");
|
Err!(Database(error!(
|
||||||
Err(Error::bad_database(
|
"Failed to find any media keys for MXC {mxc:?} in our database."
|
||||||
"Failed to find any media keys for the provided MXC in our database (MXC does not exist)",
|
)))
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,23 +136,16 @@ impl Service {
|
||||||
let all_keys = self.db.get_all_media_keys();
|
let all_keys = self.db.get_all_media_keys();
|
||||||
|
|
||||||
let user_duration: SystemTime = match cyborgtime::parse_duration(&time) {
|
let user_duration: SystemTime = match cyborgtime::parse_duration(&time) {
|
||||||
Ok(duration) => {
|
Err(e) => return Err!(Database(error!("Failed to parse specified time duration: {e}"))),
|
||||||
debug!("Parsed duration: {:?}", duration);
|
Ok(duration) => SystemTime::now()
|
||||||
debug!("System time now: {:?}", SystemTime::now());
|
.checked_sub(duration)
|
||||||
SystemTime::now().checked_sub(duration).ok_or_else(|| {
|
.ok_or(err!(Arithmetic("Duration {duration:?} is too large")))?,
|
||||||
Error::bad_database("Duration specified is not valid against the current system time")
|
|
||||||
})?
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
error!("Failed to parse user-specified time duration: {}", e);
|
|
||||||
return Err(Error::bad_database("Failed to parse user-specified time duration."));
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut remote_mxcs: Vec<String> = vec![];
|
let mut remote_mxcs: Vec<String> = vec![];
|
||||||
|
|
||||||
for key in all_keys {
|
for key in all_keys {
|
||||||
debug!("Full MXC key from database: {:?}", key);
|
debug!("Full MXC key from database: {key:?}");
|
||||||
|
|
||||||
// we need to get the MXC URL from the first part of the key (the first 0xff /
|
// we need to get the MXC URL from the first part of the key (the first 0xff /
|
||||||
// 255 push). this is all necessary because of conduit using magic keys for
|
// 255 push). this is all necessary because of conduit using magic keys for
|
||||||
|
@ -162,24 +154,19 @@ impl Service {
|
||||||
let mxc = parts
|
let mxc = parts
|
||||||
.next()
|
.next()
|
||||||
.map(|bytes| {
|
.map(|bytes| {
|
||||||
utils::string_from_bytes(bytes).map_err(|e| {
|
utils::string_from_bytes(bytes)
|
||||||
error!("Failed to parse MXC unicode bytes from our database: {}", e);
|
.map_err(|e| err!(Database(error!("Failed to parse MXC unicode bytes from our database: {e}"))))
|
||||||
Error::bad_database("Failed to parse MXC unicode bytes from our database")
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
|
||||||
let Some(mxc_s) = mxc else {
|
let Some(mxc_s) = mxc else {
|
||||||
return Err(Error::bad_database(
|
return Err!(Database("Parsed MXC URL unicode bytes from database but still is None"));
|
||||||
"Parsed MXC URL unicode bytes from database but still is None",
|
|
||||||
));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("Parsed MXC key to URL: {}", mxc_s);
|
debug!("Parsed MXC key to URL: {mxc_s}");
|
||||||
|
|
||||||
let mxc = OwnedMxcUri::from(mxc_s);
|
let mxc = OwnedMxcUri::from(mxc_s);
|
||||||
if mxc.server_name() == Ok(services().globals.server_name()) {
|
if mxc.server_name() == Ok(services().globals.server_name()) {
|
||||||
debug!("Ignoring local media MXC: {}", mxc);
|
debug!("Ignoring local media MXC: {mxc}");
|
||||||
// ignore our own MXC URLs as this would be local media.
|
// ignore our own MXC URLs as this would be local media.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -198,14 +185,14 @@ impl Service {
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if force {
|
if force {
|
||||||
error!("Could not delete MXC path {:?}: {:?}. Skipping...", path, err);
|
error!("Could not delete MXC path {path:?}: {err:?}. Skipping...");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return Err(err.into());
|
return Err(err.into());
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
debug!("File created at: {:?}", file_created_at);
|
|
||||||
|
|
||||||
|
debug!("File created at: {file_created_at:?}");
|
||||||
if file_created_at <= user_duration {
|
if file_created_at <= user_duration {
|
||||||
debug!("File is within user duration, pushing to list of file paths and keys to delete.");
|
debug!("File is within user duration, pushing to list of file paths and keys to delete.");
|
||||||
remote_mxcs.push(mxc.to_string());
|
remote_mxcs.push(mxc.to_string());
|
||||||
|
@ -215,15 +202,12 @@ impl Service {
|
||||||
debug!(
|
debug!(
|
||||||
"Finished going through all our media in database for eligible keys to delete, checking if these are empty"
|
"Finished going through all our media in database for eligible keys to delete, checking if these are empty"
|
||||||
);
|
);
|
||||||
|
|
||||||
if remote_mxcs.is_empty() {
|
if remote_mxcs.is_empty() {
|
||||||
return Err(Error::bad_database("Did not found any eligible MXCs to delete."));
|
return Err!(Database("Did not found any eligible MXCs to delete."));
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("Deleting media now in the past \"{:?}\".", user_duration);
|
debug!("Deleting media now in the past {user_duration:?}.");
|
||||||
|
|
||||||
let mut deletion_count: usize = 0;
|
let mut deletion_count: usize = 0;
|
||||||
|
|
||||||
for mxc in remote_mxcs {
|
for mxc in remote_mxcs {
|
||||||
debug!("Deleting MXC {mxc} from database and filesystem");
|
debug!("Deleting MXC {mxc} from database and filesystem");
|
||||||
self.delete(&mxc).await?;
|
self.delete(&mxc).await?;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{collections::BTreeMap, mem::size_of, sync::Arc};
|
use std::{collections::BTreeMap, mem::size_of, sync::Arc};
|
||||||
|
|
||||||
use conduit::{debug_info, utils, warn, Error, Result};
|
use conduit::{debug_info, err, utils, warn, Err, Error, Result};
|
||||||
use database::{Database, Map};
|
use database::{Database, Map};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::client::{device::Device, error::ErrorKind, filter::FilterDefinition},
|
api::client::{device::Device, error::ErrorKind, filter::FilterDefinition},
|
||||||
|
@ -87,19 +87,19 @@ impl Data {
|
||||||
let mut parts = bytes.split(|&b| b == 0xFF);
|
let mut parts = bytes.split(|&b| b == 0xFF);
|
||||||
let user_bytes = parts
|
let user_bytes = parts
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| Error::bad_database("User ID in token_userdeviceid is invalid."))?;
|
.ok_or_else(|| err!(Database("User ID in token_userdeviceid is invalid.")))?;
|
||||||
let device_bytes = parts
|
let device_bytes = parts
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| Error::bad_database("Device ID in token_userdeviceid is invalid."))?;
|
.ok_or_else(|| err!(Database("Device ID in token_userdeviceid is invalid.")))?;
|
||||||
|
|
||||||
Ok(Some((
|
Ok(Some((
|
||||||
UserId::parse(
|
UserId::parse(
|
||||||
utils::string_from_bytes(user_bytes)
|
utils::string_from_bytes(user_bytes)
|
||||||
.map_err(|_| Error::bad_database("User ID in token_userdeviceid is invalid unicode."))?,
|
.map_err(|e| err!(Database("User ID in token_userdeviceid is invalid unicode. {e}")))?,
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("User ID in token_userdeviceid is invalid."))?,
|
.map_err(|e| err!(Database("User ID in token_userdeviceid is invalid. {e}")))?,
|
||||||
utils::string_from_bytes(device_bytes)
|
utils::string_from_bytes(device_bytes)
|
||||||
.map_err(|_| Error::bad_database("Device ID in token_userdeviceid is invalid."))?,
|
.map_err(|e| err!(Database("Device ID in token_userdeviceid is invalid. {e}")))?,
|
||||||
)))
|
)))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -109,9 +109,9 @@ impl Data {
|
||||||
Box::new(self.userid_password.iter().map(|(bytes, _)| {
|
Box::new(self.userid_password.iter().map(|(bytes, _)| {
|
||||||
UserId::parse(
|
UserId::parse(
|
||||||
utils::string_from_bytes(&bytes)
|
utils::string_from_bytes(&bytes)
|
||||||
.map_err(|_| Error::bad_database("User ID in userid_password is invalid unicode."))?,
|
.map_err(|e| err!(Database("User ID in userid_password is invalid unicode. {e}")))?,
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("User ID in userid_password is invalid."))
|
.map_err(|e| err!(Database("User ID in userid_password is invalid. {e}")))
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ impl Data {
|
||||||
.map_or(Ok(None), |bytes| {
|
.map_or(Ok(None), |bytes| {
|
||||||
Ok(Some(
|
Ok(Some(
|
||||||
utils::string_from_bytes(&bytes)
|
utils::string_from_bytes(&bytes)
|
||||||
.map_err(|_| Error::bad_database("Displayname in db is invalid."))?,
|
.map_err(|e| err!(Database("Displayname in db is invalid. {e}")))?,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -188,10 +188,8 @@ impl Data {
|
||||||
self.userid_avatarurl
|
self.userid_avatarurl
|
||||||
.get(user_id.as_bytes())?
|
.get(user_id.as_bytes())?
|
||||||
.map(|bytes| {
|
.map(|bytes| {
|
||||||
let s_bytes = utils::string_from_bytes(&bytes).map_err(|e| {
|
let s_bytes = utils::string_from_bytes(&bytes)
|
||||||
warn!("Avatar URL in db is invalid: {}", e);
|
.map_err(|e| err!(Database(warn!("Avatar URL in db is invalid: {e}"))))?;
|
||||||
Error::bad_database("Avatar URL in db is invalid.")
|
|
||||||
})?;
|
|
||||||
let mxc_uri: OwnedMxcUri = s_bytes.into();
|
let mxc_uri: OwnedMxcUri = s_bytes.into();
|
||||||
Ok(mxc_uri)
|
Ok(mxc_uri)
|
||||||
})
|
})
|
||||||
|
@ -215,10 +213,7 @@ impl Data {
|
||||||
self.userid_blurhash
|
self.userid_blurhash
|
||||||
.get(user_id.as_bytes())?
|
.get(user_id.as_bytes())?
|
||||||
.map(|bytes| {
|
.map(|bytes| {
|
||||||
let s = utils::string_from_bytes(&bytes)
|
utils::string_from_bytes(&bytes).map_err(|e| err!(Database("Avatar URL in db is invalid. {e}")))
|
||||||
.map_err(|_| Error::bad_database("Avatar URL in db is invalid."))?;
|
|
||||||
|
|
||||||
Ok(s)
|
|
||||||
})
|
})
|
||||||
.transpose()
|
.transpose()
|
||||||
}
|
}
|
||||||
|
@ -314,9 +309,9 @@ impl Data {
|
||||||
bytes
|
bytes
|
||||||
.rsplit(|&b| b == 0xFF)
|
.rsplit(|&b| b == 0xFF)
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| Error::bad_database("UserDevice ID in db is invalid."))?,
|
.ok_or_else(|| err!(Database("UserDevice ID in db is invalid.")))?,
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("Device ID in userdeviceid_metadata is invalid."))?
|
.map_err(|e| err!(Database("Device ID in userdeviceid_metadata is invalid. {e}")))?
|
||||||
.into())
|
.into())
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
@ -330,13 +325,9 @@ impl Data {
|
||||||
|
|
||||||
// should not be None, but we shouldn't assert either lol...
|
// should not be None, but we shouldn't assert either lol...
|
||||||
if self.userdeviceid_metadata.get(&userdeviceid)?.is_none() {
|
if self.userdeviceid_metadata.get(&userdeviceid)?.is_none() {
|
||||||
warn!(
|
return Err!(Database(error!(
|
||||||
"Called set_token for a non-existent user \"{}\" and/or device ID \"{}\" with no metadata in database",
|
"User {user_id:?} does not exist or device ID {device_id:?} has no metadata."
|
||||||
user_id, device_id
|
)));
|
||||||
);
|
|
||||||
return Err(Error::bad_database(
|
|
||||||
"User does not exist or device ID has no metadata in database.",
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove old token
|
// Remove old token
|
||||||
|
@ -366,14 +357,9 @@ impl Data {
|
||||||
// Only existing devices should be able to call this, but we shouldn't assert
|
// Only existing devices should be able to call this, but we shouldn't assert
|
||||||
// either...
|
// either...
|
||||||
if self.userdeviceid_metadata.get(&key)?.is_none() {
|
if self.userdeviceid_metadata.get(&key)?.is_none() {
|
||||||
warn!(
|
return Err!(Database(error!(
|
||||||
"Called add_one_time_key for a non-existent user \"{}\" and/or device ID \"{}\" with no metadata in \
|
"User {user_id:?} does not exist or device ID {device_id:?} has no metadata."
|
||||||
database",
|
)));
|
||||||
user_id, device_id
|
|
||||||
);
|
|
||||||
return Err(Error::bad_database(
|
|
||||||
"User does not exist or device ID has no metadata in database.",
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
key.push(0xFF);
|
key.push(0xFF);
|
||||||
|
@ -401,7 +387,7 @@ impl Data {
|
||||||
.get(user_id.as_bytes())?
|
.get(user_id.as_bytes())?
|
||||||
.map_or(Ok(0), |bytes| {
|
.map_or(Ok(0), |bytes| {
|
||||||
utils::u64_from_bytes(&bytes)
|
utils::u64_from_bytes(&bytes)
|
||||||
.map_err(|_| Error::bad_database("Count in roomid_lastroomactiveupdate is invalid."))
|
.map_err(|e| err!(Database("Count in roomid_lastroomactiveupdate is invalid. {e}")))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,11 +415,10 @@ impl Data {
|
||||||
serde_json::from_slice(
|
serde_json::from_slice(
|
||||||
key.rsplit(|&b| b == 0xFF)
|
key.rsplit(|&b| b == 0xFF)
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| Error::bad_database("OneTimeKeyId in db is invalid."))?,
|
.ok_or_else(|| err!(Database("OneTimeKeyId in db is invalid.")))?,
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("OneTimeKeyId in db is invalid."))?,
|
.map_err(|e| err!(Database("OneTimeKeyId in db is invalid. {e}")))?,
|
||||||
serde_json::from_slice(&value)
|
serde_json::from_slice(&value).map_err(|e| err!(Database("OneTimeKeys in db are invalid. {e}")))?,
|
||||||
.map_err(|_| Error::bad_database("OneTimeKeys in db are invalid."))?,
|
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.transpose()
|
.transpose()
|
||||||
|
@ -457,9 +442,9 @@ impl Data {
|
||||||
bytes
|
bytes
|
||||||
.rsplit(|&b| b == 0xFF)
|
.rsplit(|&b| b == 0xFF)
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| Error::bad_database("OneTimeKey ID in db is invalid."))?,
|
.ok_or_else(|| err!(Database("OneTimeKey ID in db is invalid.")))?,
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("DeviceKeyId in db is invalid."))?
|
.map_err(|e| err!(Database("DeviceKeyId in db is invalid. {e}")))?
|
||||||
.algorithm(),
|
.algorithm(),
|
||||||
)
|
)
|
||||||
}) {
|
}) {
|
||||||
|
@ -581,19 +566,19 @@ impl Data {
|
||||||
.get(&key)?
|
.get(&key)?
|
||||||
.ok_or(Error::BadRequest(ErrorKind::InvalidParam, "Tried to sign nonexistent key."))?,
|
.ok_or(Error::BadRequest(ErrorKind::InvalidParam, "Tried to sign nonexistent key."))?,
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("key in keyid_key is invalid."))?;
|
.map_err(|e| err!(Database("key in keyid_key is invalid. {e}")))?;
|
||||||
|
|
||||||
let signatures = cross_signing_key
|
let signatures = cross_signing_key
|
||||||
.get_mut("signatures")
|
.get_mut("signatures")
|
||||||
.ok_or_else(|| Error::bad_database("key in keyid_key has no signatures field."))?
|
.ok_or_else(|| err!(Database("key in keyid_key has no signatures field.")))?
|
||||||
.as_object_mut()
|
.as_object_mut()
|
||||||
.ok_or_else(|| Error::bad_database("key in keyid_key has invalid signatures field."))?
|
.ok_or_else(|| err!(Database("key in keyid_key has invalid signatures field.")))?
|
||||||
.entry(sender_id.to_string())
|
.entry(sender_id.to_string())
|
||||||
.or_insert_with(|| serde_json::Map::new().into());
|
.or_insert_with(|| serde_json::Map::new().into());
|
||||||
|
|
||||||
signatures
|
signatures
|
||||||
.as_object_mut()
|
.as_object_mut()
|
||||||
.ok_or_else(|| Error::bad_database("signatures in keyid_key for a user is invalid."))?
|
.ok_or_else(|| err!(Database("signatures in keyid_key for a user is invalid.")))?
|
||||||
.insert(signature.0, signature.1.into());
|
.insert(signature.0, signature.1.into());
|
||||||
|
|
||||||
self.keyid_key.insert(
|
self.keyid_key.insert(
|
||||||
|
@ -640,7 +625,7 @@ impl Data {
|
||||||
Error::bad_database("User ID in devicekeychangeid_userid is invalid unicode.")
|
Error::bad_database("User ID in devicekeychangeid_userid is invalid unicode.")
|
||||||
})?,
|
})?,
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("User ID in devicekeychangeid_userid is invalid."))
|
.map_err(|e| err!(Database("User ID in devicekeychangeid_userid is invalid. {e}")))
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -685,7 +670,7 @@ impl Data {
|
||||||
|
|
||||||
self.keyid_key.get(&key)?.map_or(Ok(None), |bytes| {
|
self.keyid_key.get(&key)?.map_or(Ok(None), |bytes| {
|
||||||
Ok(Some(
|
Ok(Some(
|
||||||
serde_json::from_slice(&bytes).map_err(|_| Error::bad_database("DeviceKeys in db are invalid."))?,
|
serde_json::from_slice(&bytes).map_err(|e| err!(Database("DeviceKeys in db are invalid. {e}")))?,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -719,7 +704,7 @@ impl Data {
|
||||||
) -> Result<Option<Raw<CrossSigningKey>>> {
|
) -> Result<Option<Raw<CrossSigningKey>>> {
|
||||||
self.keyid_key.get(key)?.map_or(Ok(None), |bytes| {
|
self.keyid_key.get(key)?.map_or(Ok(None), |bytes| {
|
||||||
let mut cross_signing_key = serde_json::from_slice::<serde_json::Value>(&bytes)
|
let mut cross_signing_key = serde_json::from_slice::<serde_json::Value>(&bytes)
|
||||||
.map_err(|_| Error::bad_database("CrossSigningKey in db is invalid."))?;
|
.map_err(|e| err!(Database("CrossSigningKey in db is invalid. {e}")))?;
|
||||||
clean_signatures(&mut cross_signing_key, sender_user, user_id, allowed_signatures)?;
|
clean_signatures(&mut cross_signing_key, sender_user, user_id, allowed_signatures)?;
|
||||||
|
|
||||||
Ok(Some(Raw::from_json(
|
Ok(Some(Raw::from_json(
|
||||||
|
@ -751,7 +736,7 @@ impl Data {
|
||||||
self.keyid_key.get(&key)?.map_or(Ok(None), |bytes| {
|
self.keyid_key.get(&key)?.map_or(Ok(None), |bytes| {
|
||||||
Ok(Some(
|
Ok(Some(
|
||||||
serde_json::from_slice(&bytes)
|
serde_json::from_slice(&bytes)
|
||||||
.map_err(|_| Error::bad_database("CrossSigningKey in db is invalid."))?,
|
.map_err(|e| err!(Database("CrossSigningKey in db is invalid. {e}")))?,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -792,7 +777,7 @@ impl Data {
|
||||||
for (_, value) in self.todeviceid_events.scan_prefix(prefix) {
|
for (_, value) in self.todeviceid_events.scan_prefix(prefix) {
|
||||||
events.push(
|
events.push(
|
||||||
serde_json::from_slice(&value)
|
serde_json::from_slice(&value)
|
||||||
.map_err(|_| Error::bad_database("Event in todeviceid_events is invalid."))?,
|
.map_err(|e| err!(Database("Event in todeviceid_events is invalid. {e}")))?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -816,7 +801,7 @@ impl Data {
|
||||||
Ok::<_, Error>((
|
Ok::<_, Error>((
|
||||||
key.clone(),
|
key.clone(),
|
||||||
utils::u64_from_bytes(&key[key.len().saturating_sub(size_of::<u64>())..key.len()])
|
utils::u64_from_bytes(&key[key.len().saturating_sub(size_of::<u64>())..key.len()])
|
||||||
.map_err(|_| Error::bad_database("ToDeviceId has invalid count bytes."))?,
|
.map_err(|e| err!(Database("ToDeviceId has invalid count bytes. {e}")))?,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.filter_map(Result::ok)
|
.filter_map(Result::ok)
|
||||||
|
@ -877,7 +862,7 @@ impl Data {
|
||||||
.get(user_id.as_bytes())?
|
.get(user_id.as_bytes())?
|
||||||
.map_or(Ok(None), |bytes| {
|
.map_or(Ok(None), |bytes| {
|
||||||
utils::u64_from_bytes(&bytes)
|
utils::u64_from_bytes(&bytes)
|
||||||
.map_err(|_| Error::bad_database("Invalid devicelistversion in db."))
|
.map_err(|e| err!(Database("Invalid devicelistversion in db. {e}")))
|
||||||
.map(Some)
|
.map(Some)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -893,7 +878,7 @@ impl Data {
|
||||||
.scan_prefix(key)
|
.scan_prefix(key)
|
||||||
.map(|(_, bytes)| {
|
.map(|(_, bytes)| {
|
||||||
serde_json::from_slice::<Device>(&bytes)
|
serde_json::from_slice::<Device>(&bytes)
|
||||||
.map_err(|_| Error::bad_database("Device in userdeviceid_metadata is invalid."))
|
.map_err(|e| err!(Database("Device in userdeviceid_metadata is invalid. {e}")))
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -920,7 +905,7 @@ impl Data {
|
||||||
let raw = self.userfilterid_filter.get(&key)?;
|
let raw = self.userfilterid_filter.get(&key)?;
|
||||||
|
|
||||||
if let Some(raw) = raw {
|
if let Some(raw) = raw {
|
||||||
serde_json::from_slice(&raw).map_err(|_| Error::bad_database("Invalid filter event in db."))
|
serde_json::from_slice(&raw).map_err(|e| err!(Database("Invalid filter event in db. {e}")))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
@ -954,7 +939,7 @@ impl Data {
|
||||||
let expires_at = u64::from_be_bytes(
|
let expires_at = u64::from_be_bytes(
|
||||||
expires_at_bytes
|
expires_at_bytes
|
||||||
.try_into()
|
.try_into()
|
||||||
.map_err(|_| Error::bad_database("expires_at in openid_userid is invalid u64."))?,
|
.map_err(|e| err!(Database("expires_at in openid_userid is invalid u64. {e}")))?,
|
||||||
);
|
);
|
||||||
|
|
||||||
if expires_at < utils::millis_since_unix_epoch() {
|
if expires_at < utils::millis_since_unix_epoch() {
|
||||||
|
@ -966,9 +951,9 @@ impl Data {
|
||||||
|
|
||||||
UserId::parse(
|
UserId::parse(
|
||||||
utils::string_from_bytes(user_bytes)
|
utils::string_from_bytes(user_bytes)
|
||||||
.map_err(|_| Error::bad_database("User ID in openid_userid is invalid unicode."))?,
|
.map_err(|e| err!(Database("User ID in openid_userid is invalid unicode. {e}")))?,
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("User ID in openid_userid is invalid."))
|
.map_err(|e| err!(Database("User ID in openid_userid is invalid. {e}")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue