Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sdk&ffi: server unstable features support for MSC4028 #3192

Merged
10 changes: 10 additions & 0 deletions bindings/matrix-sdk-ffi/src/notification_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,16 @@ impl NotificationSettings {
}
}

/// Check whether [MSC 4028 push rule][rule] is enabled on the homeserver.
///
/// [rule]: https://github.com/matrix-org/matrix-spec-proposals/blob/giomfo/push_encrypted_events/proposals/4028-push-all-encrypted-events-except-for-muted-rooms.md
pub async fn can_homeserver_push_encrypted_event_to_device(&self) -> bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a bit of logic here, and I think that this could be useful for other clients. Could this method go to the SDK, next to unstable_features, please? (and add a test for it too 🙏)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

of course! good hint. let me know if what I pushed goes in the direction of ur suggestion 👍

match self.sdk_client.unstable_features().await {
Ok(unstable_feature) => *unstable_feature.get("org.matrix.msc4028").unwrap_or(&false),
hanadi92 marked this conversation as resolved.
Show resolved Hide resolved
Err(_) => false,
}
}

/// Set whether user mentions are enabled.
pub async fn set_user_mention_enabled(
&self,
Expand Down
5 changes: 4 additions & 1 deletion crates/matrix-sdk/src/client/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use std::{fmt, sync::Arc};
use std::{collections::BTreeMap, fmt, sync::Arc};

use matrix_sdk_base::{store::StoreConfig, BaseClient};
use ruma::{
Expand Down Expand Up @@ -90,6 +90,7 @@ pub struct ClientBuilder {
request_config: RequestConfig,
respect_login_well_known: bool,
server_versions: Option<Box<[MatrixVersion]>>,
unstable_features: Option<BTreeMap<String, bool>>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unused in ClientBuilder, and can be removed. :-)

handle_refresh_tokens: bool,
base_client: Option<BaseClient>,
#[cfg(feature = "e2e-encryption")]
Expand All @@ -107,6 +108,7 @@ impl ClientBuilder {
request_config: Default::default(),
respect_login_well_known: true,
server_versions: None,
unstable_features: None,
handle_refresh_tokens: false,
base_client: None,
#[cfg(feature = "e2e-encryption")]
Expand Down Expand Up @@ -508,6 +510,7 @@ impl ClientBuilder {
http_client,
base_client,
self.server_versions,
self.unstable_features,
self.respect_login_well_known,
event_cache,
#[cfg(feature = "e2e-encryption")]
Expand Down
67 changes: 67 additions & 0 deletions crates/matrix-sdk/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@ pub(crate) struct ClientInner {
/// The Matrix versions the server supports (well-known ones only)
server_versions: OnceCell<Box<[MatrixVersion]>>,

/// The unstable features and their on/off state on the server
unstable_features: OnceCell<BTreeMap<String, bool>>,

/// Collection of locks individual client methods might want to use, either
/// to ensure that only a single call to a method happens at once or to
/// deduplicate multiple calls to a method.
Expand Down Expand Up @@ -292,6 +295,7 @@ impl ClientInner {
http_client: HttpClient,
base_client: BaseClient,
server_versions: Option<Box<[MatrixVersion]>>,
unstable_features: Option<BTreeMap<String, bool>>,
respect_login_well_known: bool,
event_cache: OnceCell<EventCache>,
#[cfg(feature = "e2e-encryption")] encryption_settings: EncryptionSettings,
Expand All @@ -305,6 +309,7 @@ impl ClientInner {
base_client,
locks: Default::default(),
server_versions: OnceCell::new_with(server_versions),
unstable_features: OnceCell::new_with(unstable_features),
typing_notice_times: Default::default(),
event_handlers: Default::default(),
notification_handlers: Default::default(),
Expand Down Expand Up @@ -1401,6 +1406,49 @@ impl Client {
Ok(server_versions)
}

/// Fetch unstable_features from homeserver
async fn request_unstable_features(&self) -> HttpResult<BTreeMap<String, bool>> {
let unstable_features: BTreeMap<String, bool> = self
.inner
.http_client
.send(
get_supported_versions::Request::new(),
None,
self.homeserver().to_string(),
None,
&[MatrixVersion::V1_0],
Default::default(),
)
.await?
.unstable_features;

Ok(unstable_features)
}

/// Get unstable features from `request_unstable_features` or cache
///
/// # Examples
///
/// ```no_run
/// # use matrix_sdk::{Client, config::SyncSettings};
/// # use url::Url;
/// # async {
/// # let homeserver = Url::parse("http://localhost:8080")?;
/// # let mut client = Client::new(homeserver).await?;
/// let unstable_features = client.unstable_features().await.unwrap();
bnjbvr marked this conversation as resolved.
Show resolved Hide resolved
/// let msc_x = unstable_features.get("msc_x").unwrap_or(&false);
/// # anyhow::Ok(()) };
/// ```
pub async fn unstable_features(&self) -> HttpResult<&BTreeMap<String, bool>> {
let unstable_features = self
.inner
.unstable_features
.get_or_try_init(|| self.request_unstable_features())
.await?;

Ok(unstable_features)
}

/// Get information of all our own devices.
///
/// # Examples
Expand Down Expand Up @@ -2006,6 +2054,7 @@ impl Client {
self.inner.http_client.clone(),
self.inner.base_client.clone_with_in_memory_state_store(),
self.inner.server_versions.get().cloned(),
self.inner.unstable_features.get().cloned(),
self.inner.respect_login_well_known,
self.inner.event_cache.clone(),
#[cfg(feature = "e2e-encryption")]
Expand Down Expand Up @@ -2269,4 +2318,22 @@ pub(crate) mod tests {
assert_eq!(result.avatar_url.clone().unwrap().to_string(), "mxc://example.me/someid");
assert!(!response.limited);
}

#[async_test]
async fn test_homeserver_server_versions() {
let server = MockServer::start().await;
let client = logged_in_client(Some(server.uri())).await;

Mock::given(method("GET"))
.and(path("_matrix/client/versions"))
.respond_with(
ResponseTemplate::new(200).set_body_json(&*test_json::api_responses::VERSIONS),
)
.mount(&server)
.await;
let unstable_features = client.request_unstable_features().await.unwrap();

assert_eq!(unstable_features.get("org.matrix.e2e_cross_signing"), Some(&true));
assert_eq!(unstable_features, client.unstable_features().await.unwrap().clone())
}
}
Loading