Merge remote-tracking branch 'upstream/main' into conduwuit-changes

This commit is contained in:
strawberry 2024-05-09 11:29:29 -04:00
commit 9e29e07ae1
44 changed files with 410 additions and 133 deletions

View File

@ -16,20 +16,20 @@ criterion = "0.5.0"
http = "1.1.0" http = "1.1.0"
js_int = "0.2.2" js_int = "0.2.2"
maplit = "1.0.2" maplit = "1.0.2"
ruma-appservice-api = { version = "0.9.0", path = "crates/ruma-appservice-api" } ruma-appservice-api = { version = "0.10.0", path = "crates/ruma-appservice-api" }
ruma-common = { version = "0.12.1", path = "crates/ruma-common" } ruma-common = { version = "0.13.0", path = "crates/ruma-common" }
ruma-client = { version = "0.12.0", path = "crates/ruma-client" } ruma-client = { version = "0.13.0", path = "crates/ruma-client" }
ruma-client-api = { version = "0.17.4", path = "crates/ruma-client-api" } ruma-client-api = { version = "0.18.0", path = "crates/ruma-client-api" }
ruma-events = { version = "0.27.11", path = "crates/ruma-events" } ruma-events = { version = "0.28.0", path = "crates/ruma-events" }
ruma-federation-api = { version = "0.8.0", path = "crates/ruma-federation-api" } ruma-federation-api = { version = "0.9.0", path = "crates/ruma-federation-api" }
ruma-html = { version = "0.1.0", path = "crates/ruma-html" } ruma-html = { version = "0.2.0", path = "crates/ruma-html" }
ruma-identifiers-validation = { version = "0.9.3", path = "crates/ruma-identifiers-validation" } ruma-identifiers-validation = { version = "0.9.5", path = "crates/ruma-identifiers-validation" }
ruma-identity-service-api = { version = "0.8.0", path = "crates/ruma-identity-service-api" } ruma-identity-service-api = { version = "0.9.0", path = "crates/ruma-identity-service-api" }
ruma-macros = { version = "=0.12.0", path = "crates/ruma-macros" } ruma-macros = { version = "=0.13.0", path = "crates/ruma-macros" }
ruma-push-gateway-api = { version = "0.8.0", path = "crates/ruma-push-gateway-api" } ruma-push-gateway-api = { version = "0.9.0", path = "crates/ruma-push-gateway-api" }
ruma-signatures = { version = "0.14.0", path = "crates/ruma-signatures" } ruma-signatures = { version = "0.15.0", path = "crates/ruma-signatures" }
ruma-server-util = { version = "0.2.0", path = "crates/ruma-server-util" } ruma-server-util = { version = "0.3.0", path = "crates/ruma-server-util" }
ruma-state-res = { version = "0.10.0", path = "crates/ruma-state-res" } ruma-state-res = { version = "0.11.0", path = "crates/ruma-state-res" }
serde = { version = "1.0.164", features = ["derive"] } serde = { version = "1.0.164", features = ["derive"] }
serde_html_form = "0.2.0" serde_html_form = "0.2.0"
serde_json = "1.0.87" serde_json = "1.0.87"

View File

@ -24,7 +24,7 @@ dependencies:
```toml ```toml
# crates.io release # crates.io release
ruma = { version = "0.9.0", features = ["..."] } ruma = { version = "0.10.0", features = ["..."] }
# git dependency # git dependency
ruma = { git = "https://github.com/ruma/ruma", branch = "main", features = ["..."] } ruma = { git = "https://github.com/ruma/ruma", branch = "main", features = ["..."] }
``` ```
@ -38,7 +38,7 @@ them as a user. Check out the documentation [on docs.rs][docs] (or on
## Status ## Status
Ruma 0.9.0 supports all events and REST endpoints of Matrix 1.8. Ruma 0.10.0 supports all events and REST endpoints of Matrix 1.10.
Various changes from in-progress or finished MSCs are also implemented, gated Various changes from in-progress or finished MSCs are also implemented, gated
behind the `unstable-mscXXXX` (where `XXXX` is the MSC number) Cargo features. behind the `unstable-mscXXXX` (where `XXXX` is the MSC number) Cargo features.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 63 KiB

View File

@ -1,9 +1,12 @@
# [unreleased] # [unreleased]
# 0.10.0
Breaking changes: Breaking changes:
* The `url` field of `Registration` is now an `Option<String>`. This should have * The `url` field of `Registration` is now an `Option<String>`. This should have
always been the case. always been the case.
- The http crate had a major version bump to version 1.1
# 0.9.0 # 0.9.0

View File

@ -7,7 +7,7 @@ license = "MIT"
name = "ruma-appservice-api" name = "ruma-appservice-api"
readme = "README.md" readme = "README.md"
repository = "https://github.com/ruma/ruma" repository = "https://github.com/ruma/ruma"
version = "0.9.0" version = "0.10.0"
edition = "2021" edition = "2021"
rust-version = { workspace = true } rust-version = { workspace = true }

View File

@ -1,11 +1,15 @@
# [unreleased] # [unreleased]
# 0.18.0
Bug fixes: Bug fixes:
- Don't require the `failures` field in the - Don't require the `failures` field in the
`ruma_client_api::keys::upload_signatures::Response` type. `ruma_client_api::keys::upload_signatures::Response` type.
- `sync::sync_events::v3::Timeline::is_empty` now returns `false` when the - `sync::sync_events::v3::Timeline::is_empty` now returns `false` when the
`limited` or `prev_batch` fields are set. `limited` or `prev_batch` fields are set.
- `login_fallback::Response` now returns the proper content type
- `sso_login[_with_provider]` responses now use the proper HTTP status code.
Breaking changes: Breaking changes:
@ -21,6 +25,10 @@ Breaking changes:
- The `retry_after_ms` field of `ErrorKind::LimitExceeded` was renamed to - The `retry_after_ms` field of `ErrorKind::LimitExceeded` was renamed to
`retry_after` and is now an `Option<RetryAfter>`, to add support for the `retry_after` and is now an `Option<RetryAfter>`, to add support for the
Retry-After header, according to MSC4041 / Matrix 1.10 Retry-After header, according to MSC4041 / Matrix 1.10
- Make `get_uiaa_fallback::v3::Response` an enum for a redirect or an HTML page.
It will now return the proper status code and headers depending on the variant
used.
- The http crate had a major version bump to version 1.1
Improvements: Improvements:

View File

@ -7,7 +7,7 @@ license = "MIT"
name = "ruma-client-api" name = "ruma-client-api"
readme = "README.md" readme = "README.md"
repository = "https://github.com/ruma/ruma" repository = "https://github.com/ruma/ruma"
version = "0.17.4" version = "0.18.0"
edition = "2021" edition = "2021"
rust-version = { workspace = true } rust-version = { workspace = true }

View File

@ -6,17 +6,22 @@ use as_variant::as_variant;
use bytes::{BufMut, Bytes}; use bytes::{BufMut, Bytes};
use ruma_common::{ use ruma_common::{
api::{ api::{
error::{FromHttpResponseError, IntoHttpError, MatrixErrorBody}, error::{
FromHttpResponseError, HeaderDeserializationError, HeaderSerializationError,
IntoHttpError, MatrixErrorBody,
},
EndpointError, OutgoingResponse, EndpointError, OutgoingResponse,
}, },
RoomVersionId, RoomVersionId,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::{from_slice as from_json_slice, Value as JsonValue}; use serde_json::{from_slice as from_json_slice, Value as JsonValue};
use thiserror::Error; use web_time::{Duration, SystemTime};
use web_time::{Duration, SystemTime, UNIX_EPOCH};
use crate::PrivOwnedStr; use crate::{
http_headers::{http_date_to_system_time, system_time_to_http_date},
PrivOwnedStr,
};
/// Deserialize and Serialize implementations for ErrorKind. /// Deserialize and Serialize implementations for ErrorKind.
/// Separate module because it's a lot of code. /// Separate module because it's a lot of code.
@ -372,9 +377,8 @@ impl EndpointError for Error {
ErrorKind::LimitExceeded { retry_after } => { ErrorKind::LimitExceeded { retry_after } => {
// The Retry-After header takes precedence over the retry_after_ms field in // The Retry-After header takes precedence over the retry_after_ms field in
// the body. // the body.
if let Some(retry_after_header) = headers if let Some(Ok(retry_after_header)) =
.get(http::header::RETRY_AFTER) headers.get(http::header::RETRY_AFTER).map(RetryAfter::try_from)
.and_then(RetryAfter::from_header_value)
{ {
*retry_after = Some(retry_after_header); *retry_after = Some(retry_after_header);
} }
@ -567,57 +571,29 @@ pub enum RetryAfter {
DateTime(SystemTime), DateTime(SystemTime),
} }
impl RetryAfter { impl TryFrom<&http::HeaderValue> for RetryAfter {
fn from_header_value(value: &http::HeaderValue) -> Option<Self> { type Error = HeaderDeserializationError;
let bytes = value.as_bytes();
if bytes.iter().all(|b| b.is_ascii_digit()) { fn try_from(value: &http::HeaderValue) -> Result<Self, Self::Error> {
if value.as_bytes().iter().all(|b| b.is_ascii_digit()) {
// It should be a duration. // It should be a duration.
Some(Self::Delay(Duration::from_secs(u64::from_str(value.to_str().ok()?).ok()?))) Ok(Self::Delay(Duration::from_secs(u64::from_str(value.to_str()?)?)))
} else { } else {
// It should be a date. // It should be a date.
let ts = date_header::parse(bytes).ok()?; Ok(Self::DateTime(http_date_to_system_time(value)?))
Some(Self::DateTime(UNIX_EPOCH.checked_add(Duration::from_secs(ts))?))
} }
} }
} }
impl TryFrom<&RetryAfter> for http::HeaderValue { impl TryFrom<&RetryAfter> for http::HeaderValue {
type Error = RetryAfterInvalidDateTime; type Error = HeaderSerializationError;
fn try_from(value: &RetryAfter) -> Result<Self, Self::Error> { fn try_from(value: &RetryAfter) -> Result<Self, Self::Error> {
match value { match value {
RetryAfter::Delay(duration) => Ok(duration.as_secs().into()), RetryAfter::Delay(duration) => Ok(duration.as_secs().into()),
RetryAfter::DateTime(time) => { RetryAfter::DateTime(time) => system_time_to_http_date(time),
let mut buffer = [0; 29];
let duration =
time.duration_since(UNIX_EPOCH).map_err(|_| RetryAfterInvalidDateTime)?;
date_header::format(duration.as_secs(), &mut buffer)
.map_err(|_| RetryAfterInvalidDateTime)?;
let value = http::HeaderValue::from_bytes(&buffer)
.expect("date_header should produce a valid header value");
Ok(value)
} }
} }
}
}
/// An error when converting a [`RetryAfter`] to a [`http::HeaderValue`].
///
/// Happens when the `DateTime` is too far in the past (before the Unix epoch) or the
/// future (after the year 9999).
#[derive(Debug, Error)]
#[allow(clippy::exhaustive_structs)]
#[error(
"Retry-After header serialization failed: the datetime is too far in the past or the future"
)]
pub struct RetryAfterInvalidDateTime;
impl From<RetryAfterInvalidDateTime> for IntoHttpError {
fn from(_value: RetryAfterInvalidDateTime) -> Self {
IntoHttpError::RetryAfterInvalidDatetime
}
} }
/// Extension trait for `FromHttpResponseError<ruma_client_api::Error>`. /// Extension trait for `FromHttpResponseError<ruma_client_api::Error>`.

View File

@ -1,10 +1,40 @@
//! Custom HTTP headers not defined in the `http` crate. //! Helpers for HTTP headers with the `http` crate.
#![allow(clippy::declare_interior_mutable_const)] #![allow(clippy::declare_interior_mutable_const)]
use http::header::HeaderName; use http::{header::HeaderName, HeaderValue};
use ruma_common::api::error::{HeaderDeserializationError, HeaderSerializationError};
use web_time::{Duration, SystemTime, UNIX_EPOCH};
/// The [`Cross-Origin-Resource-Policy`] HTTP response header. /// The [`Cross-Origin-Resource-Policy`] HTTP response header.
/// ///
/// [`Cross-Origin-Resource-Policy`]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy /// [`Cross-Origin-Resource-Policy`]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy
pub const CROSS_ORIGIN_RESOURCE_POLICY: HeaderName = pub const CROSS_ORIGIN_RESOURCE_POLICY: HeaderName =
HeaderName::from_static("cross-origin-resource-policy"); HeaderName::from_static("cross-origin-resource-policy");
/// Convert as `SystemTime` to a HTTP date header value.
pub fn system_time_to_http_date(
time: &SystemTime,
) -> Result<HeaderValue, HeaderSerializationError> {
let mut buffer = [0; 29];
let duration =
time.duration_since(UNIX_EPOCH).map_err(|_| HeaderSerializationError::InvalidHttpDate)?;
date_header::format(duration.as_secs(), &mut buffer)
.map_err(|_| HeaderSerializationError::InvalidHttpDate)?;
Ok(http::HeaderValue::from_bytes(&buffer)
.expect("date_header should produce a valid header value"))
}
/// Convert a header value representing a HTTP date to a `SystemTime`.
pub fn http_date_to_system_time(
value: &HeaderValue,
) -> Result<SystemTime, HeaderDeserializationError> {
let bytes = value.as_bytes();
let ts = date_header::parse(bytes).map_err(|_| HeaderDeserializationError::InvalidHttpDate)?;
UNIX_EPOCH
.checked_add(Duration::from_secs(ts))
.ok_or(HeaderDeserializationError::InvalidHttpDate)
}

View File

@ -5,7 +5,7 @@
//! [spec]: https://spec.matrix.org/latest/client-server-api/#login-fallback //! [spec]: https://spec.matrix.org/latest/client-server-api/#login-fallback
use ruma_common::{ use ruma_common::{
api::{request, response, Metadata}, api::{request, Metadata},
metadata, OwnedDeviceId, metadata, OwnedDeviceId,
}; };
@ -35,14 +35,6 @@ pub struct Request {
pub initial_device_display_name: Option<String>, pub initial_device_display_name: Option<String>,
} }
/// Response type for the `login_fallback` endpoint.
#[response(error = crate::Error)]
pub struct Response {
/// HTML to return to client.
#[ruma_api(raw_body)]
pub body: Vec<u8>,
}
impl Request { impl Request {
/// Creates a new `Request` with the given auth type and session ID. /// Creates a new `Request` with the given auth type and session ID.
pub fn new( pub fn new(
@ -53,9 +45,49 @@ impl Request {
} }
} }
/// Response type for the `login_fallback` endpoint.
#[derive(Debug, Clone)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct Response {
/// HTML to return to client.
pub body: Vec<u8>,
}
impl Response { impl Response {
/// Creates a new `Response` with the given HTML body. /// Creates a new `Response` with the given HTML body.
pub fn new(body: Vec<u8>) -> Self { pub fn new(body: Vec<u8>) -> Self {
Self { body } Self { body }
} }
} }
#[cfg(feature = "server")]
impl ruma_common::api::OutgoingResponse for Response {
fn try_into_http_response<T: Default + bytes::BufMut>(
self,
) -> Result<http::Response<T>, ruma_common::api::error::IntoHttpError> {
Ok(http::Response::builder()
.status(http::StatusCode::OK)
.header(http::header::CONTENT_TYPE, "text/html")
.body(ruma_common::serde::slice_to_buf(&self.body))?)
}
}
#[cfg(feature = "client")]
impl ruma_common::api::IncomingResponse for Response {
type EndpointError = crate::Error;
fn try_from_http_response<T: AsRef<[u8]>>(
response: http::Response<T>,
) -> Result<Self, ruma_common::api::error::FromHttpResponseError<Self::EndpointError>> {
use ruma_common::api::{error::FromHttpResponseError, EndpointError};
if response.status().as_u16() >= 400 {
return Err(FromHttpResponseError::Server(Self::EndpointError::from_http_response(
response,
)));
}
let body = response.into_body().as_ref().to_owned();
Ok(Self { body })
}
}

View File

@ -32,7 +32,7 @@ pub mod v3 {
} }
/// Response type for the `sso_login` endpoint. /// Response type for the `sso_login` endpoint.
#[response(error = crate::Error)] #[response(error = crate::Error, status = FOUND)]
pub struct Response { pub struct Response {
/// Redirect URL to the SSO identity provider. /// Redirect URL to the SSO identity provider.
#[ruma_api(header = LOCATION)] #[ruma_api(header = LOCATION)]

View File

@ -38,7 +38,7 @@ pub mod v3 {
} }
/// Response type for the `sso_login_with_provider` endpoint. /// Response type for the `sso_login_with_provider` endpoint.
#[response(error = crate::Error)] #[response(error = crate::Error, status = FOUND)]
pub struct Response { pub struct Response {
/// Redirect URL to the SSO identity provider. /// Redirect URL to the SSO identity provider.
#[ruma_api(header = LOCATION)] #[ruma_api(header = LOCATION)]

View File

@ -7,9 +7,8 @@ pub mod v3 {
//! //!
//! [spec]: https://spec.matrix.org/latest/client-server-api/#fallback //! [spec]: https://spec.matrix.org/latest/client-server-api/#fallback
use http::header::LOCATION;
use ruma_common::{ use ruma_common::{
api::{request, response, Metadata}, api::{request, Metadata},
metadata, metadata,
}; };
@ -35,19 +34,6 @@ pub mod v3 {
pub session: String, pub session: String,
} }
/// Response type for the `authorize_fallback` endpoint.
#[response(error = crate::Error)]
#[derive(Default)]
pub struct Response {
/// Optional URI to redirect to.
#[ruma_api(header = LOCATION)]
pub redirect_url: Option<String>,
/// HTML to return to client.
#[ruma_api(raw_body)]
pub body: Vec<u8>,
}
impl Request { impl Request {
/// Creates a new `Request` with the given auth type and session ID. /// Creates a new `Request` with the given auth type and session ID.
pub fn new(auth_type: String, session: String) -> Self { pub fn new(auth_type: String, session: String) -> Self {
@ -55,15 +41,172 @@ pub mod v3 {
} }
} }
impl Response { /// Response type for the `authorize_fallback` endpoint.
/// Creates a new `Response` with the given HTML body. #[derive(Debug, Clone)]
pub fn new(body: Vec<u8>) -> Self { #[allow(clippy::exhaustive_enums)]
Self { redirect_url: None, body } pub enum Response {
/// The response is a redirect.
Redirect(Redirect),
/// The response is an HTML page.
Html(HtmlPage),
} }
/// Creates a new `Response` with the given redirect URL and an empty body. /// The data of a redirect.
#[derive(Debug, Clone)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct Redirect {
/// The URL to redirect the user to.
pub url: String,
}
/// The data of a HTML page.
#[derive(Debug, Clone)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct HtmlPage {
/// The body of the HTML page.
pub body: Vec<u8>,
}
impl Response {
/// Creates a new HTML `Response` with the given HTML body.
pub fn html(body: Vec<u8>) -> Self {
Self::Html(HtmlPage { body })
}
/// Creates a new HTML `Response` with the given redirect URL.
pub fn redirect(url: String) -> Self { pub fn redirect(url: String) -> Self {
Self { redirect_url: Some(url), body: Vec::new() } Self::Redirect(Redirect { url })
}
}
#[cfg(feature = "server")]
impl ruma_common::api::OutgoingResponse for Response {
fn try_into_http_response<T: Default + bytes::BufMut>(
self,
) -> Result<http::Response<T>, ruma_common::api::error::IntoHttpError> {
match self {
Response::Redirect(Redirect { url }) => Ok(http::Response::builder()
.status(http::StatusCode::FOUND)
.header(http::header::LOCATION, url)
.body(T::default())?),
Response::Html(HtmlPage { body }) => Ok(http::Response::builder()
.status(http::StatusCode::OK)
.header(http::header::CONTENT_TYPE, "text/html; charset=utf-8")
.body(ruma_common::serde::slice_to_buf(&body))?),
}
}
}
#[cfg(feature = "client")]
impl ruma_common::api::IncomingResponse for Response {
type EndpointError = crate::Error;
fn try_from_http_response<T: AsRef<[u8]>>(
response: http::Response<T>,
) -> Result<Self, ruma_common::api::error::FromHttpResponseError<Self::EndpointError>>
{
use ruma_common::api::{
error::{DeserializationError, FromHttpResponseError, HeaderDeserializationError},
EndpointError,
};
if response.status().as_u16() >= 400 {
return Err(FromHttpResponseError::Server(
Self::EndpointError::from_http_response(response),
));
}
if response.status() == http::StatusCode::FOUND {
let Some(location) = response.headers().get(http::header::LOCATION) else {
return Err(DeserializationError::Header(
HeaderDeserializationError::MissingHeader(
http::header::LOCATION.to_string(),
),
)
.into());
};
let url = location.to_str()?;
return Ok(Self::Redirect(Redirect { url: url.to_owned() }));
}
let body = response.into_body().as_ref().to_owned();
Ok(Self::Html(HtmlPage { body }))
}
}
#[cfg(all(test, any(feature = "client", feature = "server")))]
mod tests {
use assert_matches2::assert_matches;
use http::header::{CONTENT_TYPE, LOCATION};
#[cfg(feature = "client")]
use ruma_common::api::IncomingResponse;
#[cfg(feature = "server")]
use ruma_common::api::OutgoingResponse;
use super::Response;
#[cfg(feature = "client")]
#[test]
fn incoming_redirect() {
use super::Redirect;
let http_response = http::Response::builder()
.status(http::StatusCode::FOUND)
.header(LOCATION, "http://localhost/redirect")
.body(Vec::<u8>::new())
.unwrap();
let response = Response::try_from_http_response(http_response).unwrap();
assert_matches!(response, Response::Redirect(Redirect { url }));
assert_eq!(url, "http://localhost/redirect");
}
#[cfg(feature = "client")]
#[test]
fn incoming_html() {
use super::HtmlPage;
let http_response = http::Response::builder()
.status(http::StatusCode::OK)
.header(CONTENT_TYPE, "text/html; charset=utf-8")
.body(b"<h1>My Page</h1>")
.unwrap();
let response = Response::try_from_http_response(http_response).unwrap();
assert_matches!(response, Response::Html(HtmlPage { body }));
assert_eq!(body, b"<h1>My Page</h1>");
}
#[cfg(feature = "server")]
#[test]
fn outgoing_redirect() {
let response = Response::redirect("http://localhost/redirect".to_owned());
let http_response = response.try_into_http_response::<Vec<u8>>().unwrap();
assert_eq!(http_response.status(), http::StatusCode::FOUND);
assert_eq!(
http_response.headers().get(LOCATION).unwrap().to_str().unwrap(),
"http://localhost/redirect"
);
assert!(http_response.into_body().is_empty());
}
#[cfg(feature = "server")]
#[test]
fn outgoing_html() {
let response = Response::html(b"<h1>My Page</h1>".to_vec());
let http_response = response.try_into_http_response::<Vec<u8>>().unwrap();
assert_eq!(http_response.status(), http::StatusCode::OK);
assert_eq!(
http_response.headers().get(CONTENT_TYPE).unwrap().to_str().unwrap(),
"text/html; charset=utf-8"
);
assert_eq!(http_response.into_body(), b"<h1>My Page</h1>");
} }
} }
} }

View File

@ -1,5 +1,7 @@
# [unreleased] # [unreleased]
# 0.13.0
Breaking changes: Breaking changes:
- Remove `isahc` feature - Remove `isahc` feature

View File

@ -7,7 +7,7 @@ license = "MIT"
name = "ruma-client" name = "ruma-client"
readme = "README.md" readme = "README.md"
repository = "https://github.com/ruma/ruma" repository = "https://github.com/ruma/ruma"
version = "0.12.0" version = "0.13.0"
edition = "2021" edition = "2021"
rust-version = { workspace = true } rust-version = { workspace = true }

View File

@ -1,10 +1,13 @@
# [unreleased] # [unreleased]
# 0.13.0
Bug fixes: Bug fixes:
- Allow to deserialize `Ruleset` with missing fields. - Allow to deserialize `Ruleset` with missing fields.
Breaking changes: Breaking changes:
- The power levels fields in `PushConditionRoomCtx` are grouped in an optional `power_levels` field. - The power levels fields in `PushConditionRoomCtx` are grouped in an optional `power_levels` field.
If the field is missing, push rules that depend on it will never match. However, this allows to If the field is missing, push rules that depend on it will never match. However, this allows to
match the `.m.rule.invite_for_me` push rule because usually the `invite_state` doesn't include match the `.m.rule.invite_for_me` push rule because usually the `invite_state` doesn't include
@ -14,6 +17,7 @@ Breaking changes:
- `deserialize_as_f64_or_string` has been extended to also support parsing integers, and renamed to - `deserialize_as_f64_or_string` has been extended to also support parsing integers, and renamed to
`deserialize_as_number_or_string` to reflect that. `deserialize_as_number_or_string` to reflect that.
- The http crate had a major version bump to version 1.1 - The http crate had a major version bump to version 1.1
- `IntoHttpError::Header` now contains a `HeaderSerializationError`
Improvements: Improvements:

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ruma-common" name = "ruma-common"
version = "0.12.1" version = "0.13.0"
description = "Common types for other ruma crates." description = "Common types for other ruma crates."
homepage = "https://ruma.dev/" homepage = "https://ruma.dev/"
keywords = ["matrix", "chat", "messaging", "ruma"] keywords = ["matrix", "chat", "messaging", "ruma"]

View File

@ -2,7 +2,7 @@
//! converting between http requests / responses and ruma's representation of //! converting between http requests / responses and ruma's representation of
//! matrix API requests / responses. //! matrix API requests / responses.
use std::{error::Error as StdError, fmt, sync::Arc}; use std::{error::Error as StdError, fmt, num::ParseIntError, sync::Arc};
use bytes::{BufMut, Bytes}; use bytes::{BufMut, Bytes};
use serde_json::{from_slice as from_json_slice, Value as JsonValue}; use serde_json::{from_slice as from_json_slice, Value as JsonValue};
@ -127,20 +127,19 @@ pub enum IntoHttpError {
/// Header serialization failed. /// Header serialization failed.
#[error("header serialization failed: {0}")] #[error("header serialization failed: {0}")]
Header(#[from] http::header::InvalidHeaderValue), Header(#[from] HeaderSerializationError),
/// Retry-After header serialization failed because the datetime provided is after the year
/// 9999.
#[error(
"Retry-After header serialization failed: the year of the datetime is bigger than 9999"
)]
RetryAfterInvalidDatetime,
/// HTTP request construction failed. /// HTTP request construction failed.
#[error("HTTP request construction failed: {0}")] #[error("HTTP request construction failed: {0}")]
Http(#[from] http::Error), Http(#[from] http::Error),
} }
impl From<http::header::InvalidHeaderValue> for IntoHttpError {
fn from(value: http::header::InvalidHeaderValue) -> Self {
Self::Header(value.into())
}
}
/// An error when converting a http request to one of ruma's endpoint-specific request types. /// An error when converting a http request to one of ruma's endpoint-specific request types.
#[derive(Debug, Error)] #[derive(Debug, Error)]
#[non_exhaustive] #[non_exhaustive]
@ -258,13 +257,21 @@ impl From<http::header::ToStrError> for DeserializationError {
} }
} }
/// An error with the http headers. /// An error when deserializing the HTTP headers.
#[derive(Debug, Error)] #[derive(Debug, Error)]
#[non_exhaustive] #[non_exhaustive]
pub enum HeaderDeserializationError { pub enum HeaderDeserializationError {
/// Failed to convert `http::header::HeaderValue` to `str`. /// Failed to convert `http::header::HeaderValue` to `str`.
#[error("{0}")] #[error("{0}")]
ToStrError(http::header::ToStrError), ToStrError(#[from] http::header::ToStrError),
/// Failed to convert `http::header::HeaderValue` to an integer.
#[error("{0}")]
ParseIntError(#[from] ParseIntError),
/// Failed to parse a HTTP date from a `http::header::Value`.
#[error("failed to parse HTTP date")]
InvalidHttpDate,
/// The given required header is missing. /// The given required header is missing.
#[error("missing header `{0}`")] #[error("missing header `{0}`")]
@ -303,3 +310,19 @@ impl fmt::Display for IncorrectArgumentCount {
} }
impl StdError for IncorrectArgumentCount {} impl StdError for IncorrectArgumentCount {}
/// An error when serializing the HTTP headers.
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum HeaderSerializationError {
/// Failed to convert a header value to `http::header::HeaderValue`.
#[error(transparent)]
ToHeaderValue(#[from] http::header::InvalidHeaderValue),
/// The `SystemTime` could not be converted to a HTTP date.
///
/// This only happens if the `SystemTime` provided is too far in the past (before the Unix
/// epoch) or the future (after the year 9999).
#[error("invalid HTTP date")]
InvalidHttpDate,
}

View File

@ -1,5 +1,7 @@
# [unreleased] # [unreleased]
# 0.28.0
Bug fixes: Bug fixes:
- The `MembershipState::Invite` to `MembershipState::Knock` membership change - The `MembershipState::Invite` to `MembershipState::Knock` membership change

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ruma-events" name = "ruma-events"
version = "0.27.11" version = "0.28.0"
description = "Serializable types for the events in the Matrix specification." description = "Serializable types for the events in the Matrix specification."
homepage = "https://ruma.dev/" homepage = "https://ruma.dev/"
keywords = ["matrix", "chat", "messaging", "ruma"] keywords = ["matrix", "chat", "messaging", "ruma"]

View File

@ -1,16 +1,19 @@
# [unreleased] # [unreleased]
# 0.9.0
Breaking changes: Breaking changes:
* Use `RawValue` to represent body of `/v1/send_join` request, rather than incorrectly using - Use `RawValue` to represent body of `/v1/send_join` request, rather than incorrectly using
query parameters query parameters
- The http crate had a major version bump to version 1.1
Improvements: Improvements:
* Implement `From<SpaceHierarchyParentSummary>` for `SpaceHierarchyChildSummary` - Implement `From<SpaceHierarchyParentSummary>` for `SpaceHierarchyChildSummary`
* Add unstable support for optional `via` field on the `create_invite` endpoint request from - Add unstable support for optional `via` field on the `create_invite` endpoint request from
MSC4125 behind the `unstable-msc4125` feature. MSC4125 behind the `unstable-msc4125` feature.
* Add unstable support for the `report_content` endpoint from MSC3843 behind the - Add unstable support for the `report_content` endpoint from MSC3843 behind the
`unstable-msc3843` feature. `unstable-msc3843` feature.
# 0.8.0 # 0.8.0

View File

@ -7,7 +7,7 @@ license = "MIT"
name = "ruma-federation-api" name = "ruma-federation-api"
readme = "README.md" readme = "README.md"
repository = "https://github.com/ruma/ruma" repository = "https://github.com/ruma/ruma"
version = "0.8.0" version = "0.9.0"
edition = "2021" edition = "2021"
rust-version = { workspace = true } rust-version = { workspace = true }

View File

@ -1,5 +1,7 @@
# [unreleased] # [unreleased]
# 0.2.0
Breaking Changes: Breaking Changes:
- Do not export `Node` in the public API, it is not usable on its own and it is - Do not export `Node` in the public API, it is not usable on its own and it is

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ruma-html" name = "ruma-html"
version = "0.1.0" version = "0.2.0"
description = "Opinionated HTML parsing and manipulating." description = "Opinionated HTML parsing and manipulating."
homepage = "https://ruma.dev/" homepage = "https://ruma.dev/"
keywords = ["matrix", "ruma", "html", "parser"] keywords = ["matrix", "ruma", "html", "parser"]

View File

@ -1,5 +1,7 @@
# [unreleased] # [unreleased]
# 0.9.5
Bug fixes: Bug fixes:
- Allow underscores (`_`) when validating MXC URIs. - Allow underscores (`_`) when validating MXC URIs.
@ -12,6 +14,10 @@ Improvements:
- Point links to the Matrix 1.10 specification - Point links to the Matrix 1.10 specification
# 0.9.4
Yanked because it was created from the wrong branch
# 0.9.3 # 0.9.3
Improvements: Improvements:

View File

@ -4,7 +4,7 @@ description = "Validation logic for ruma-common and ruma-macros"
homepage = "https://ruma.dev/" homepage = "https://ruma.dev/"
repository = "https://github.com/ruma/ruma" repository = "https://github.com/ruma/ruma"
license = "MIT" license = "MIT"
version = "0.9.3" version = "0.9.5"
edition = "2021" edition = "2021"
rust-version = { workspace = true } rust-version = { workspace = true }

View File

@ -1,5 +1,15 @@
# [unreleased] # [unreleased]
# 0.9.0
Breaking changes:
- The http crate had a major version bump to version 1.1
Improvements:
- The type returned by `get_supported_versions::known_versions()` was simplified
# 0.8.0 # 0.8.0
Breaking changes: Breaking changes:

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ruma-identity-service-api" name = "ruma-identity-service-api"
version = "0.8.0" version = "0.9.0"
description = "Types for the endpoints in the Matrix identity service API." description = "Types for the endpoints in the Matrix identity service API."
homepage = "https://ruma.dev/" homepage = "https://ruma.dev/"
keywords = ["matrix", "chat", "messaging", "ruma"] keywords = ["matrix", "chat", "messaging", "ruma"]

View File

@ -7,7 +7,7 @@ license = "MIT"
name = "ruma-macros" name = "ruma-macros"
readme = "README.md" readme = "README.md"
repository = "https://github.com/ruma/ruma" repository = "https://github.com/ruma/ruma"
version = "0.12.0" version = "0.13.0"
edition = "2021" edition = "2021"
rust-version = { workspace = true } rust-version = { workspace = true }

View File

@ -1,5 +1,11 @@
# [unreleased] # [unreleased]
# 0.9.0
Breaking changes:
- The http crate had a major version bump to version 1.1
# 0.8.0 # 0.8.0
No changes for this version No changes for this version

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ruma-push-gateway-api" name = "ruma-push-gateway-api"
version = "0.8.0" version = "0.9.0"
description = "Types for the endpoints in the Matrix push gateway API." description = "Types for the endpoints in the Matrix push gateway API."
homepage = "https://ruma.dev/" homepage = "https://ruma.dev/"
keywords = ["matrix", "chat", "messaging", "ruma"] keywords = ["matrix", "chat", "messaging", "ruma"]

View File

@ -1,5 +1,11 @@
# [unreleased] # [unreleased]
# 0.3.0
Breaking changes:
- The headers dependency was upgraded to 0.4.0
# 0.2.0 # 0.2.0
No changes for this version No changes for this version

View File

@ -7,7 +7,7 @@ license = "MIT"
name = "ruma-server-util" name = "ruma-server-util"
readme = "README.md" readme = "README.md"
repository = "https://github.com/ruma/ruma" repository = "https://github.com/ruma/ruma"
version = "0.2.0" version = "0.3.0"
edition = "2021" edition = "2021"
rust-version = { workspace = true } rust-version = { workspace = true }

View File

@ -1,5 +1,9 @@
# [unreleased] # [unreleased]
# 0.15.0
No changes for this version
# 0.14.0 # 0.14.0
Breaking changes: Breaking changes:

View File

@ -7,7 +7,7 @@ license = "MIT"
name = "ruma-signatures" name = "ruma-signatures"
readme = "README.md" readme = "README.md"
repository = "https://github.com/ruma/ruma" repository = "https://github.com/ruma/ruma"
version = "0.14.0" version = "0.15.0"
edition = "2021" edition = "2021"
[package.metadata.docs.rs] [package.metadata.docs.rs]

View File

@ -1,11 +1,17 @@
# [unreleased] # [unreleased]
# 0.11.0
Breaking changes:
- Upgrade dependencies
Bug fixes: Bug fixes:
* Disallow `invite` -> `knock` membership transition - Disallow `invite` -> `knock` membership transition.
* The spec was determined to be right about rejecting it in the first place: The spec was determined to be right about rejecting it in the first place:
<https://github.com/matrix-org/matrix-spec/pull/1717> <https://github.com/matrix-org/matrix-spec/pull/1717>
* Perform extra redaction checks on room versions 1 and 2, rather than for - Perform extra redaction checks on room versions 1 and 2, rather than for
version 3 and onwards version 3 and onwards
# 0.10.0 # 0.10.0

View File

@ -7,7 +7,7 @@ homepage = "https://ruma.dev/"
repository = "https://github.com/ruma/ruma" repository = "https://github.com/ruma/ruma"
readme = "README.md" readme = "README.md"
license = "MIT" license = "MIT"
version = "0.10.0" version = "0.11.0"
edition = "2021" edition = "2021"
rust-version = { workspace = true } rust-version = { workspace = true }

View File

@ -1,7 +1,12 @@
# [unreleased] # [unreleased]
# 0.10.0
- Bump MSRV to 1.75 - Bump MSRV to 1.75
- re-export the `ruma-events`'s `unstable-msc2867` feature, manually marking rooms as unread - The http crate had a major version bump to version 1.1
- The `client-isahc` feature was removed
- Most ruma crates had breaking changes, refer to their changelogs for more
details
# 0.9.4 # 0.9.4

View File

@ -7,7 +7,7 @@ homepage = "https://ruma.dev/"
repository = "https://github.com/ruma/ruma" repository = "https://github.com/ruma/ruma"
readme = "README.md" readme = "README.md"
license = "MIT" license = "MIT"
version = "0.9.4" version = "0.10.0"
edition = "2021" edition = "2021"
rust-version = { workspace = true } rust-version = { workspace = true }

View File

@ -5,7 +5,7 @@ edition = "2021"
publish = false publish = false
[dependencies] [dependencies]
ruma = { version = "0.9.4", path = "../../crates/ruma", features = ["client-api-c", "client-ext-client-api", "client-hyper-native-tls", "rand"] } ruma = { version = "0.10.0", path = "../../crates/ruma", features = ["client-api-c", "client-ext-client-api", "client-hyper-native-tls", "rand"] }
anyhow = "1.0.37" anyhow = "1.0.37"
tokio = { version = "1.0.1", features = ["macros", "rt"] } tokio = { version = "1.0.1", features = ["macros", "rt"] }

View File

@ -5,7 +5,7 @@ edition = "2021"
publish = false publish = false
[dependencies] [dependencies]
ruma = { version = "0.9.4", path = "../../crates/ruma", features = ["client-api-c", "client-ext-client-api", "client-hyper-native-tls", "rand"] } ruma = { version = "0.10.0", path = "../../crates/ruma", features = ["client-api-c", "client-ext-client-api", "client-hyper-native-tls", "rand"] }
# For building locally: use the git dependencies below. # For building locally: use the git dependencies below.
# Browse the source at this revision here: https://github.com/ruma/ruma/tree/f161c8117c706fc52089999e1f406cf34276ec9d # Browse the source at this revision here: https://github.com/ruma/ruma/tree/f161c8117c706fc52089999e1f406cf34276ec9d
# ruma = { git = "https://github.com/ruma/ruma", rev = "f161c8117c706fc52089999e1f406cf34276ec9d", features = ["client-api-c", "client", "client-hyper-native-tls", "events"] } # ruma = { git = "https://github.com/ruma/ruma", rev = "f161c8117c706fc52089999e1f406cf34276ec9d", features = ["client-api-c", "client", "client-hyper-native-tls", "events"] }

View File

@ -6,6 +6,6 @@ publish = false
[dependencies] [dependencies]
anyhow = "1.0.37" anyhow = "1.0.37"
ruma = { version = "0.9.4", path = "../../crates/ruma", features = ["client-api-c", "client-ext-client-api", "client-hyper-native-tls"] } ruma = { version = "0.10.0", path = "../../crates/ruma", features = ["client-api-c", "client-ext-client-api", "client-hyper-native-tls"] }
tokio = { version = "1.0.1", features = ["macros", "rt"] } tokio = { version = "1.0.1", features = ["macros", "rt"] }
tokio-stream = { version = "0.1.1", default-features = false } tokio-stream = { version = "0.1.1", default-features = false }

View File

@ -105,6 +105,11 @@ impl Package {
/// ///
/// If `update` is `true`, update the changelog for the release of the given version. /// If `update` is `true`, update the changelog for the release of the given version.
pub fn changes(&self, update: bool) -> Result<String> { pub fn changes(&self, update: bool) -> Result<String> {
if self.name == "ruma-macros" {
// ruma-macros doesn't have a changelog and won't create a tag.
return Ok(String::new());
}
let mut changelog_path = self.manifest_path.clone(); let mut changelog_path = self.manifest_path.clone();
changelog_path.set_file_name("CHANGELOG.md"); changelog_path.set_file_name("CHANGELOG.md");

View File

@ -58,7 +58,7 @@ impl ReleaseTask {
let config = crate::Config::load()?.github; let config = crate::Config::load()?.github;
let http_client = Client::new(); let http_client = Client::builder().user_agent("ruma xtask").build()?;
Ok(Self { metadata, package, version, http_client, config, dry_run }) Ok(Self { metadata, package, version, http_client, config, dry_run })
} }
@ -67,7 +67,8 @@ impl ReleaseTask {
pub(crate) fn run(&mut self) -> Result<()> { pub(crate) fn run(&mut self) -> Result<()> {
let title = &self.title(); let title = &self.title();
let prerelease = !self.version.pre.is_empty(); let prerelease = !self.version.pre.is_empty();
let publish_only = self.package.name == "ruma-identifiers-validation"; let publish_only =
["ruma-identifiers-validation", "ruma-macros"].contains(&self.package.name.as_str());
println!( println!(
"Starting {} for {title}…", "Starting {} for {title}…",