1
0
Fork 0
mirror of https://forgejo.ellis.link/continuwuation/continuwuity.git synced 2025-07-28 10:48:30 +00:00
continuwuity/src/api/client/presence.rs
strawberry 405167fc3f add harmless check for presence PUT matching sender user
this is already done but we just don't error and always
use the sender user. match synapse behaviour where we check
and error.

Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-07-24 01:41:25 -04:00

87 lines
2.3 KiB
Rust

use std::time::Duration;
use ruma::api::client::{
error::ErrorKind,
presence::{get_presence, set_presence},
};
use crate::{services, Error, Result, Ruma};
/// # `PUT /_matrix/client/r0/presence/{userId}/status`
///
/// Sets the presence state of the sender user.
pub(crate) async fn set_presence_route(body: Ruma<set_presence::v3::Request>) -> Result<set_presence::v3::Response> {
if !services().globals.allow_local_presence() {
return Err(Error::BadRequest(ErrorKind::forbidden(), "Presence is disabled on this server"));
}
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
if sender_user != &body.user_id && body.appservice_info.is_none() {
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"Not allowed to set presence of other users",
));
}
services()
.presence
.set_presence(sender_user, &body.presence, None, None, body.status_msg.clone())?;
Ok(set_presence::v3::Response {})
}
/// # `GET /_matrix/client/r0/presence/{userId}/status`
///
/// Gets the presence state of the given user.
///
/// - Only works if you share a room with the user
pub(crate) async fn get_presence_route(body: Ruma<get_presence::v3::Request>) -> Result<get_presence::v3::Response> {
if !services().globals.allow_local_presence() {
return Err(Error::BadRequest(ErrorKind::forbidden(), "Presence is disabled on this server"));
}
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
let mut presence_event = None;
for _room_id in services()
.rooms
.user
.get_shared_rooms(vec![sender_user.clone(), body.user_id.clone()])?
{
if let Some(presence) = services().presence.get_presence(&body.user_id)? {
presence_event = Some(presence);
break;
}
}
if let Some(presence) = presence_event {
let status_msg = if presence
.content
.status_msg
.as_ref()
.is_some_and(String::is_empty)
{
None
} else {
presence.content.status_msg
};
Ok(get_presence::v3::Response {
// TODO: Should ruma just use the presenceeventcontent type here?
status_msg,
currently_active: presence.content.currently_active,
last_active_ago: presence
.content
.last_active_ago
.map(|millis| Duration::from_millis(millis.into())),
presence: presence.content.presence,
})
} else {
Err(Error::BadRequest(
ErrorKind::NotFound,
"Presence state for this user was not found",
))
}
}