1
0
Fork 0
mirror of https://forgejo.ellis.link/continuwuation/continuwuity.git synced 2025-07-28 02:38:30 +00:00
continuwuity/src/api/client/push.rs

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

372 lines
12 KiB
Rust
Raw Normal View History

2020-07-30 18:14:47 +02:00
use ruma::{
api::client::{
error::ErrorKind,
2022-02-18 15:33:14 +01:00
push::{
2021-01-24 16:05:52 +01:00
delete_pushrule, get_pushers, get_pushrule, get_pushrule_actions, get_pushrule_enabled, get_pushrules_all,
2021-01-26 21:53:03 -05:00
set_pusher, set_pushrule, set_pushrule_actions, set_pushrule_enabled, RuleScope,
2021-01-24 16:05:52 +01:00
},
2020-07-30 18:14:47 +02:00
},
2022-04-07 13:22:10 +02:00
events::{push_rules::PushRulesEvent, GlobalAccountDataEventType},
push::{InsertPushRuleError, RemovePushRuleError, Ruleset},
2020-07-30 18:14:47 +02:00
};
2022-10-05 20:34:31 +02:00
use crate::{services, Error, Result, Ruma};
/// # `GET /_matrix/client/r0/pushrules/`
2021-08-31 19:14:37 +02:00
///
/// Retrieves the push rules event for this user.
pub(crate) async fn get_pushrules_all_route(
2022-02-18 15:33:14 +01:00
body: Ruma<get_pushrules_all::v3::Request>,
) -> Result<get_pushrules_all::v3::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
let event =
services()
.account_data
.get(None, sender_user, GlobalAccountDataEventType::PushRules.to_string().into())?;
if let Some(event) = event {
let account_data = serde_json::from_str::<PushRulesEvent>(event.get())
.map_err(|_| Error::bad_database("Invalid account data event in db."))?
.content;
Ok(get_pushrules_all::v3::Response {
global: account_data.global,
})
} else {
services().account_data.update(
None,
sender_user,
GlobalAccountDataEventType::PushRules.to_string().into(),
&serde_json::to_value(PushRulesEvent {
content: ruma::events::push_rules::PushRulesEventContent {
global: Ruleset::server_default(sender_user),
},
})
.expect("to json always works"),
)?;
Ok(get_pushrules_all::v3::Response {
global: Ruleset::server_default(sender_user),
})
}
2020-07-30 18:14:47 +02:00
}
2021-08-31 19:14:37 +02:00
/// # `GET /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}`
///
/// Retrieves a single specified push rule for this user.
pub(crate) async fn get_pushrule_route(body: Ruma<get_pushrule::v3::Request>) -> Result<get_pushrule::v3::Response> {
2021-01-24 16:05:52 +01:00
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
2022-10-05 15:33:57 +02:00
let event = services()
2021-01-24 16:05:52 +01:00
.account_data
2022-04-06 21:31:29 +02:00
.get(None, sender_user, GlobalAccountDataEventType::PushRules.to_string().into())?
2021-01-24 16:05:52 +01:00
.ok_or(Error::BadRequest(ErrorKind::NotFound, "PushRules event not found."))?;
2022-10-05 15:33:57 +02:00
let account_data = serde_json::from_str::<PushRulesEvent>(event.get())
.map_err(|_| Error::bad_database("Invalid account data event in db."))?
.content;
let rule = account_data
.global
.get(body.kind.clone(), &body.rule_id)
.map(Into::into);
2021-01-24 16:05:52 +01:00
if let Some(rule) = rule {
2022-02-18 15:33:14 +01:00
Ok(get_pushrule::v3::Response {
rule,
})
2021-01-24 16:05:52 +01:00
} else {
Err(Error::BadRequest(ErrorKind::NotFound, "Push rule not found."))
2021-01-24 16:05:52 +01:00
}
}
2021-08-31 19:14:37 +02:00
/// # `PUT /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}`
///
/// Creates a single specified push rule for this user.
pub(crate) async fn set_pushrule_route(body: Ruma<set_pushrule::v3::Request>) -> Result<set_pushrule::v3::Response> {
2021-12-15 13:58:25 +01:00
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
let body = body.body;
2022-12-14 13:09:10 +01:00
if body.scope != RuleScope::Global {
2021-01-24 16:05:52 +01:00
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"Scopes other than 'global' are not supported.",
));
}
2022-10-05 15:33:57 +02:00
let event = services()
2021-01-24 16:05:52 +01:00
.account_data
2022-04-06 21:31:29 +02:00
.get(None, sender_user, GlobalAccountDataEventType::PushRules.to_string().into())?
2021-01-24 16:05:52 +01:00
.ok_or(Error::BadRequest(ErrorKind::NotFound, "PushRules event not found."))?;
2022-10-05 15:33:57 +02:00
let mut account_data = serde_json::from_str::<PushRulesEvent>(event.get())
.map_err(|_| Error::bad_database("Invalid account data event in db."))?;
if let Err(error) =
account_data
.content
.global
.insert(body.rule.clone(), body.after.as_deref(), body.before.as_deref())
{
let err = match error {
InsertPushRuleError::ServerDefaultRuleId => Error::BadRequest(
ErrorKind::InvalidParam,
"Rule IDs starting with a dot are reserved for server-default rules.",
),
InsertPushRuleError::InvalidRuleId => {
Error::BadRequest(ErrorKind::InvalidParam, "Rule ID containing invalid characters.")
},
InsertPushRuleError::RelativeToServerDefaultRule => Error::BadRequest(
ErrorKind::InvalidParam,
"Can't place a push rule relatively to a server-default rule.",
),
InsertPushRuleError::UnknownRuleId => {
Error::BadRequest(ErrorKind::NotFound, "The before or after rule could not be found.")
},
InsertPushRuleError::BeforeHigherThanAfter => Error::BadRequest(
ErrorKind::InvalidParam,
"The before rule has a higher priority than the after rule.",
),
_ => Error::BadRequest(ErrorKind::InvalidParam, "Invalid data."),
};
return Err(err);
2021-01-24 16:05:52 +01:00
}
services().account_data.update(
2022-04-06 21:31:29 +02:00
None,
sender_user,
GlobalAccountDataEventType::PushRules.to_string().into(),
2022-10-05 15:33:57 +02:00
&serde_json::to_value(account_data).expect("to json value always works"),
2022-04-06 21:31:29 +02:00
)?;
2022-02-18 15:33:14 +01:00
Ok(set_pushrule::v3::Response {})
2020-07-30 18:14:47 +02:00
}
2021-08-31 19:14:37 +02:00
/// # `GET /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}/actions`
///
/// Gets the actions of a single specified push rule for this user.
pub(crate) async fn get_pushrule_actions_route(
2022-12-14 13:09:10 +01:00
body: Ruma<get_pushrule_actions::v3::Request>,
2022-02-18 15:33:14 +01:00
) -> Result<get_pushrule_actions::v3::Response> {
2021-01-24 16:05:52 +01:00
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
2022-12-17 09:21:19 +01:00
if body.scope != RuleScope::Global {
2021-01-24 16:05:52 +01:00
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"Scopes other than 'global' are not supported.",
));
}
2022-10-05 15:33:57 +02:00
let event = services()
2021-01-24 16:05:52 +01:00
.account_data
2022-04-06 21:31:29 +02:00
.get(None, sender_user, GlobalAccountDataEventType::PushRules.to_string().into())?
2021-01-24 16:05:52 +01:00
.ok_or(Error::BadRequest(ErrorKind::NotFound, "PushRules event not found."))?;
2022-10-05 15:33:57 +02:00
let account_data = serde_json::from_str::<PushRulesEvent>(event.get())
.map_err(|_| Error::bad_database("Invalid account data event in db."))?
.content;
2022-10-05 15:33:57 +02:00
let global = account_data.global;
let actions = global
.get(body.kind.clone(), &body.rule_id)
.map(|rule| rule.actions().to_owned())
.ok_or(Error::BadRequest(ErrorKind::NotFound, "Push rule not found."))?;
Ok(get_pushrule_actions::v3::Response {
actions,
})
2021-01-24 16:05:52 +01:00
}
2021-08-31 19:14:37 +02:00
/// # `PUT /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}/actions`
///
/// Sets the actions of a single specified push rule for this user.
pub(crate) async fn set_pushrule_actions_route(
2022-12-14 13:09:10 +01:00
body: Ruma<set_pushrule_actions::v3::Request>,
2022-02-18 15:33:14 +01:00
) -> Result<set_pushrule_actions::v3::Response> {
2021-01-24 16:05:52 +01:00
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
2022-12-14 13:09:10 +01:00
if body.scope != RuleScope::Global {
2021-01-24 16:05:52 +01:00
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"Scopes other than 'global' are not supported.",
));
}
2022-10-05 15:33:57 +02:00
let event = services()
2021-01-24 16:05:52 +01:00
.account_data
2022-04-06 21:31:29 +02:00
.get(None, sender_user, GlobalAccountDataEventType::PushRules.to_string().into())?
2021-01-24 16:05:52 +01:00
.ok_or(Error::BadRequest(ErrorKind::NotFound, "PushRules event not found."))?;
2022-10-05 15:33:57 +02:00
let mut account_data = serde_json::from_str::<PushRulesEvent>(event.get())
.map_err(|_| Error::bad_database("Invalid account data event in db."))?;
if account_data
.content
.global
.set_actions(body.kind.clone(), &body.rule_id, body.actions.clone())
.is_err()
{
return Err(Error::BadRequest(ErrorKind::NotFound, "Push rule not found."));
}
services().account_data.update(
2022-04-06 21:31:29 +02:00
None,
sender_user,
GlobalAccountDataEventType::PushRules.to_string().into(),
2022-10-05 15:33:57 +02:00
&serde_json::to_value(account_data).expect("to json value always works"),
2022-04-06 21:31:29 +02:00
)?;
2022-02-18 15:33:14 +01:00
Ok(set_pushrule_actions::v3::Response {})
2021-01-24 16:05:52 +01:00
}
2021-08-31 19:14:37 +02:00
/// # `GET /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}/enabled`
///
/// Gets the enabled status of a single specified push rule for this user.
pub(crate) async fn get_pushrule_enabled_route(
2022-12-14 13:09:10 +01:00
body: Ruma<get_pushrule_enabled::v3::Request>,
2022-02-18 15:33:14 +01:00
) -> Result<get_pushrule_enabled::v3::Response> {
2021-01-24 16:05:52 +01:00
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
2022-12-14 13:09:10 +01:00
if body.scope != RuleScope::Global {
2021-01-24 16:05:52 +01:00
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"Scopes other than 'global' are not supported.",
));
}
2022-10-05 15:33:57 +02:00
let event = services()
2021-01-24 16:05:52 +01:00
.account_data
2022-04-06 21:31:29 +02:00
.get(None, sender_user, GlobalAccountDataEventType::PushRules.to_string().into())?
2021-01-24 16:05:52 +01:00
.ok_or(Error::BadRequest(ErrorKind::NotFound, "PushRules event not found."))?;
2022-10-05 15:33:57 +02:00
let account_data = serde_json::from_str::<PushRulesEvent>(event.get())
.map_err(|_| Error::bad_database("Invalid account data event in db."))?;
2022-10-05 15:33:57 +02:00
let global = account_data.content.global;
let enabled = global
.get(body.kind.clone(), &body.rule_id)
.map(ruma::push::AnyPushRuleRef::enabled)
.ok_or(Error::BadRequest(ErrorKind::NotFound, "Push rule not found."))?;
2022-02-18 15:33:14 +01:00
Ok(get_pushrule_enabled::v3::Response {
enabled,
})
2021-01-24 16:05:52 +01:00
}
2021-08-31 19:14:37 +02:00
/// # `PUT /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}/enabled`
///
/// Sets the enabled status of a single specified push rule for this user.
pub(crate) async fn set_pushrule_enabled_route(
2022-12-14 13:09:10 +01:00
body: Ruma<set_pushrule_enabled::v3::Request>,
2022-02-18 15:33:14 +01:00
) -> Result<set_pushrule_enabled::v3::Response> {
2021-01-24 16:05:52 +01:00
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
2022-12-14 13:09:10 +01:00
if body.scope != RuleScope::Global {
2021-01-24 16:05:52 +01:00
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"Scopes other than 'global' are not supported.",
));
}
2022-10-05 15:33:57 +02:00
let event = services()
2021-01-24 16:05:52 +01:00
.account_data
2022-04-06 21:31:29 +02:00
.get(None, sender_user, GlobalAccountDataEventType::PushRules.to_string().into())?
2021-01-24 16:05:52 +01:00
.ok_or(Error::BadRequest(ErrorKind::NotFound, "PushRules event not found."))?;
2022-10-05 15:33:57 +02:00
let mut account_data = serde_json::from_str::<PushRulesEvent>(event.get())
.map_err(|_| Error::bad_database("Invalid account data event in db."))?;
if account_data
.content
.global
.set_enabled(body.kind.clone(), &body.rule_id, body.enabled)
.is_err()
{
return Err(Error::BadRequest(ErrorKind::NotFound, "Push rule not found."));
2021-01-24 16:05:52 +01:00
}
services().account_data.update(
2022-04-06 21:31:29 +02:00
None,
sender_user,
GlobalAccountDataEventType::PushRules.to_string().into(),
2022-10-05 15:33:57 +02:00
&serde_json::to_value(account_data).expect("to json value always works"),
2022-04-06 21:31:29 +02:00
)?;
2022-02-18 15:33:14 +01:00
Ok(set_pushrule_enabled::v3::Response {})
2020-07-30 18:14:47 +02:00
}
2021-08-31 19:14:37 +02:00
/// # `DELETE /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}`
///
/// Deletes a single specified push rule for this user.
pub(crate) async fn delete_pushrule_route(
body: Ruma<delete_pushrule::v3::Request>,
) -> Result<delete_pushrule::v3::Response> {
2021-01-24 16:05:52 +01:00
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
2022-12-14 13:09:10 +01:00
if body.scope != RuleScope::Global {
2021-01-24 16:05:52 +01:00
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"Scopes other than 'global' are not supported.",
));
}
2022-10-05 15:33:57 +02:00
let event = services()
2021-01-24 16:05:52 +01:00
.account_data
2022-04-06 21:31:29 +02:00
.get(None, sender_user, GlobalAccountDataEventType::PushRules.to_string().into())?
2021-01-24 16:05:52 +01:00
.ok_or(Error::BadRequest(ErrorKind::NotFound, "PushRules event not found."))?;
2022-10-05 15:33:57 +02:00
let mut account_data = serde_json::from_str::<PushRulesEvent>(event.get())
.map_err(|_| Error::bad_database("Invalid account data event in db."))?;
if let Err(error) = account_data
.content
.global
.remove(body.kind.clone(), &body.rule_id)
{
let err = match error {
RemovePushRuleError::ServerDefault => {
Error::BadRequest(ErrorKind::InvalidParam, "Cannot delete a server-default pushrule.")
},
RemovePushRuleError::NotFound => Error::BadRequest(ErrorKind::NotFound, "Push rule not found."),
_ => Error::BadRequest(ErrorKind::InvalidParam, "Invalid data."),
};
return Err(err);
2021-01-24 16:05:52 +01:00
}
services().account_data.update(
2022-04-06 21:31:29 +02:00
None,
sender_user,
GlobalAccountDataEventType::PushRules.to_string().into(),
2022-10-05 15:33:57 +02:00
&serde_json::to_value(account_data).expect("to json value always works"),
2022-04-06 21:31:29 +02:00
)?;
2022-02-18 15:33:14 +01:00
Ok(delete_pushrule::v3::Response {})
2021-01-24 16:05:52 +01:00
}
2021-08-31 19:14:37 +02:00
/// # `GET /_matrix/client/r0/pushers`
///
/// Gets all currently active pushers for the sender user.
pub(crate) async fn get_pushers_route(body: Ruma<get_pushers::v3::Request>) -> Result<get_pushers::v3::Response> {
2021-03-16 18:00:26 +01:00
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
2022-02-18 15:33:14 +01:00
Ok(get_pushers::v3::Response {
pushers: services().pusher.get_pushers(sender_user)?,
})
2020-07-30 18:14:47 +02:00
}
2021-08-31 19:14:37 +02:00
/// # `POST /_matrix/client/r0/pushers/set`
///
/// Adds a pusher for the sender user.
///
/// - TODO: Handle `append`
pub(crate) async fn set_pushers_route(body: Ruma<set_pusher::v3::Request>) -> Result<set_pusher::v3::Response> {
2021-03-16 18:00:26 +01:00
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
services().pusher.set_pusher(sender_user, &body.action)?;
2022-02-18 15:33:14 +01:00
Ok(set_pusher::v3::Response::default())
2020-07-30 18:14:47 +02:00
}