Skip to content

Commit

Permalink
feat: experimental features per user
Browse files Browse the repository at this point in the history
  • Loading branch information
hanadi92 committed Jan 30, 2024
1 parent dc99a13 commit 9f01382
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/experimental_features.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/// Endpoints in /_synapse/admin/v<x>/experimental_features/:user_id scope.
pub mod enable_features;
pub mod list_features;
2 changes: 2 additions & 0 deletions src/experimental_features/enable_features.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/// Different versions of the endpoint to enable/disable experimental features per user.
pub mod v1;
81 changes: 81 additions & 0 deletions src/experimental_features/enable_features/v1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//! [PUT /_synapse/admin/v1/experimental_features/:user_id](https://github.com/element-hq/synapse/blob/master/docs/admin_api/experimental_features.md#enablingdisabling-features)
use ruma::{
api::{request, response, Metadata},
metadata, OwnedUserId,
};
use serde::{Deserialize, Serialize};

const METADATA: Metadata = metadata! {
method: PUT,
rate_limited: false,
authentication: AccessToken,
history: {
unstable => "/_synapse/admin/v1/experimental_features/:user_id",
}
};

#[request]
#[derive(Serialize, Deserialize, PartialEq)]
pub struct Request {
/// User ID.
#[ruma_api(path)]
pub user_id: OwnedUserId,
/// Experimental features per user.
pub features: ExperimentalFeatures,
}

#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
pub struct ExperimentalFeatures {
/// Whether busy presence state is enabled.
#[serde(skip_serializing_if = "Option::is_none")]
pub msc3026: Option<bool>,
/// Whether remotely toggling push notifications for another client is enabled.
#[serde(skip_serializing_if = "Option::is_none")]
pub msc3881: Option<bool>,
/// Do not require UIA when first uploading cross-signing keys.
#[serde(skip_serializing_if = "Option::is_none")]
pub msc3967: Option<bool>,
}

#[response]
#[derive(Default)]
pub struct Response {}

impl Request {
/// Creates a `Request` with the given user ID and experimental features to enable or
/// disable for a user.
pub fn new(user_id: OwnedUserId, features: ExperimentalFeatures) -> Self {
Self { user_id, features }
}
}

impl Response {
/// Creates an empty `Response`.
pub fn new() -> Self {
Self {}
}
}

#[test]
fn test_enable_features() {
use ruma::UserId;
use std::convert::TryFrom;

let features =
ExperimentalFeatures { msc3026: Option::from(true), msc3881: None, msc3967: None };

let user_id: &UserId =
<&UserId>::try_from("@carl:example.com").expect("Failed to create UserId.");

// Check create request
let request = Request::new(user_id.to_owned(), features);

// Serialize
let serialized = serde_json::to_string(&request).expect("Failed to serialize");
assert_eq!(serialized, "{\"user_id\":\"@carl:example.com\",\"features\":{\"msc3026\":true}}");

// Deserialize
let deserialized: Request = serde_json::from_str(&serialized).expect("Failed to deserialize");
assert_eq!(deserialized, request);
}
2 changes: 2 additions & 0 deletions src/experimental_features/list_features.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/// Different versions of the endpoint to list experimental features per user.
pub mod v1;
66 changes: 66 additions & 0 deletions src/experimental_features/list_features/v1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//! [GET /_synapse/admin/v1/experimental_features/:user_id](https://github.com/element-hq/synapse/blob/develop/docs/admin_api/experimental_features.md#listing-enabled-features)
use crate::experimental_features::enable_features::v1::ExperimentalFeatures;
use ruma::{
api::{request, response, Metadata},
metadata, OwnedUserId
};
use serde::{Deserialize, Serialize};

const METADATA: Metadata = metadata! {
method: GET,
rate_limited: false,
authentication: AccessToken,
history: {
unstable => "/_synapse/admin/v1/experimental_features/:user_id",
}
};

#[request]
#[derive(Serialize, Deserialize, PartialEq)]
pub struct Request {
/// User ID.
#[ruma_api(path)]
pub user_id: OwnedUserId,
}

#[response]
#[derive(Serialize, Deserialize, PartialEq)]
pub struct Response {
/// Experimental features per user.
pub features: ExperimentalFeatures,
}

impl Request {
/// Creates a `Request` with the given user ID.
pub fn new(user_id: OwnedUserId) -> Self {
Self { user_id }
}
}

impl Response {
/// Creates a `Response` with experimental features for the user.
pub fn new(features: ExperimentalFeatures) -> Self {
Self { features }
}
}

#[test]
fn test_list_features() {
let response = Response {
features: ExperimentalFeatures {
msc3026: Option::from(false),
msc3881: None,
msc3967: None,
},
};

let json_str = "{\"features\":{\"msc3026\":false}}";
// Deserialize
let deserialized: Response = serde_json::from_str(json_str).expect("Failed to deserialize");
assert_eq!(deserialized, response);

// Serialize
let serialized = serde_json::to_string(&response).expect("Failed to serialize");
assert_eq!(serialized, json_str);
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::fmt;

pub mod account_validity;
pub mod background_updates;
pub mod experimental_features;
pub mod register_users;
pub mod rooms;
pub mod users;
Expand Down

0 comments on commit 9f01382

Please sign in to comment.