mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2025-09-11 21:13:02 +02:00
Compare commits
23 commits
cda40e8f9f
...
3df64bd931
Author | SHA1 | Date | |
---|---|---|---|
|
3df64bd931 | ||
|
cb80b1839b | ||
|
e545e5abe4 | ||
|
560881d481 | ||
|
28d5c15738 | ||
|
fe46b18279 | ||
|
0975200711 | ||
|
194c6c23e7 | ||
|
f8e4cf1efc | ||
|
c9082a61f7 | ||
|
8317e32873 | ||
|
cb4cbc6070 | ||
|
5f1095c800 | ||
|
f9ae2375d8 | ||
|
8c264d64bc | ||
|
a1403ca748 | ||
|
10b111a777 | ||
|
373df527a3 | ||
|
5833aedc99 | ||
|
cd238219de | ||
|
d3dd435ead | ||
|
9b83368458 | ||
|
920fc0c54b |
23 changed files with 90 additions and 318 deletions
5
.github/FUNDING.yml
vendored
5
.github/FUNDING.yml
vendored
|
@ -1,5 +0,0 @@
|
||||||
github: [JadedBlueEyes]
|
|
||||||
# Doesn't support an array, so we can only list nex
|
|
||||||
ko_fi: nexy7574
|
|
||||||
custom:
|
|
||||||
- https://ko-fi.com/JadedBlueEyes
|
|
22
Cargo.lock
generated
22
Cargo.lock
generated
|
@ -3798,7 +3798,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma"
|
name = "ruma"
|
||||||
version = "0.10.1"
|
version = "0.10.1"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=9b65f83981f6f53d185ce77da37aaef9dfd764a9#9b65f83981f6f53d185ce77da37aaef9dfd764a9"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assign",
|
"assign",
|
||||||
"js_int",
|
"js_int",
|
||||||
|
@ -3818,7 +3818,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-appservice-api"
|
name = "ruma-appservice-api"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=9b65f83981f6f53d185ce77da37aaef9dfd764a9#9b65f83981f6f53d185ce77da37aaef9dfd764a9"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
|
@ -3830,7 +3830,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-client-api"
|
name = "ruma-client-api"
|
||||||
version = "0.18.0"
|
version = "0.18.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=9b65f83981f6f53d185ce77da37aaef9dfd764a9#9b65f83981f6f53d185ce77da37aaef9dfd764a9"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"as_variant",
|
"as_variant",
|
||||||
"assign",
|
"assign",
|
||||||
|
@ -3853,7 +3853,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-common"
|
name = "ruma-common"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=9b65f83981f6f53d185ce77da37aaef9dfd764a9#9b65f83981f6f53d185ce77da37aaef9dfd764a9"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"as_variant",
|
"as_variant",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
|
@ -3885,7 +3885,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-events"
|
name = "ruma-events"
|
||||||
version = "0.28.1"
|
version = "0.28.1"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=9b65f83981f6f53d185ce77da37aaef9dfd764a9#9b65f83981f6f53d185ce77da37aaef9dfd764a9"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"as_variant",
|
"as_variant",
|
||||||
"indexmap 2.9.0",
|
"indexmap 2.9.0",
|
||||||
|
@ -3910,7 +3910,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-federation-api"
|
name = "ruma-federation-api"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=9b65f83981f6f53d185ce77da37aaef9dfd764a9#9b65f83981f6f53d185ce77da37aaef9dfd764a9"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"headers",
|
"headers",
|
||||||
|
@ -3932,7 +3932,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-identifiers-validation"
|
name = "ruma-identifiers-validation"
|
||||||
version = "0.9.5"
|
version = "0.9.5"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=9b65f83981f6f53d185ce77da37aaef9dfd764a9#9b65f83981f6f53d185ce77da37aaef9dfd764a9"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
|
@ -3941,7 +3941,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-identity-service-api"
|
name = "ruma-identity-service-api"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=9b65f83981f6f53d185ce77da37aaef9dfd764a9#9b65f83981f6f53d185ce77da37aaef9dfd764a9"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
|
@ -3951,7 +3951,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-macros"
|
name = "ruma-macros"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=9b65f83981f6f53d185ce77da37aaef9dfd764a9#9b65f83981f6f53d185ce77da37aaef9dfd764a9"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
|
@ -3966,7 +3966,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-push-gateway-api"
|
name = "ruma-push-gateway-api"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=9b65f83981f6f53d185ce77da37aaef9dfd764a9#9b65f83981f6f53d185ce77da37aaef9dfd764a9"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
|
@ -3978,7 +3978,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-signatures"
|
name = "ruma-signatures"
|
||||||
version = "0.15.0"
|
version = "0.15.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=9b65f83981f6f53d185ce77da37aaef9dfd764a9#9b65f83981f6f53d185ce77da37aaef9dfd764a9"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"ed25519-dalek",
|
"ed25519-dalek",
|
||||||
|
|
|
@ -350,7 +350,7 @@ version = "0.1.2"
|
||||||
[workspace.dependencies.ruma]
|
[workspace.dependencies.ruma]
|
||||||
git = "https://forgejo.ellis.link/continuwuation/ruwuma"
|
git = "https://forgejo.ellis.link/continuwuation/ruwuma"
|
||||||
#branch = "conduwuit-changes"
|
#branch = "conduwuit-changes"
|
||||||
rev = "9b65f83981f6f53d185ce77da37aaef9dfd764a9"
|
rev = "d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||||
features = [
|
features = [
|
||||||
"compat",
|
"compat",
|
||||||
"rand",
|
"rand",
|
||||||
|
|
|
@ -7,14 +7,13 @@ use futures::{
|
||||||
io::{AsyncWriteExt, BufWriter},
|
io::{AsyncWriteExt, BufWriter},
|
||||||
lock::Mutex,
|
lock::Mutex,
|
||||||
};
|
};
|
||||||
use ruma::{EventId, UserId};
|
use ruma::EventId;
|
||||||
|
|
||||||
pub(crate) struct Context<'a> {
|
pub(crate) struct Context<'a> {
|
||||||
pub(crate) services: &'a Services,
|
pub(crate) services: &'a Services,
|
||||||
pub(crate) body: &'a [&'a str],
|
pub(crate) body: &'a [&'a str],
|
||||||
pub(crate) timer: SystemTime,
|
pub(crate) timer: SystemTime,
|
||||||
pub(crate) reply_id: Option<&'a EventId>,
|
pub(crate) reply_id: Option<&'a EventId>,
|
||||||
pub(crate) sender: Option<&'a UserId>,
|
|
||||||
pub(crate) output: Mutex<BufWriter<Vec<u8>>>,
|
pub(crate) output: Mutex<BufWriter<Vec<u8>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,10 +36,4 @@ impl Context<'_> {
|
||||||
output.write_all(s.as_bytes()).map_err(Into::into).await
|
output.write_all(s.as_bytes()).map_err(Into::into).await
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the sender as a string, or service user ID if not available
|
|
||||||
pub(crate) fn sender_or_service_user(&self) -> &UserId {
|
|
||||||
self.sender
|
|
||||||
.unwrap_or_else(|| self.services.globals.server_user.as_ref())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,6 @@ async fn process_command(services: Arc<Services>, input: &CommandInput) -> Proce
|
||||||
body: &body,
|
body: &body,
|
||||||
timer: SystemTime::now(),
|
timer: SystemTime::now(),
|
||||||
reply_id: input.reply_id.as_deref(),
|
reply_id: input.reply_id.as_deref(),
|
||||||
sender: input.sender.as_deref(),
|
|
||||||
output: BufWriter::new(Vec::new()).into(),
|
output: BufWriter::new(Vec::new()).into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -225,47 +225,6 @@ pub(super) async fn deactivate(&self, no_leave_rooms: bool, user_id: String) ->
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[admin_command]
|
|
||||||
pub(super) async fn suspend(&self, user_id: String) -> Result {
|
|
||||||
let user_id = parse_local_user_id(self.services, &user_id)?;
|
|
||||||
|
|
||||||
if user_id == self.services.globals.server_user {
|
|
||||||
return Err!("Not allowed to suspend the server service account.",);
|
|
||||||
}
|
|
||||||
|
|
||||||
if !self.services.users.exists(&user_id).await {
|
|
||||||
return Err!("User {user_id} does not exist.");
|
|
||||||
}
|
|
||||||
if self.services.users.is_admin(&user_id).await {
|
|
||||||
return Err!("Admin users cannot be suspended.");
|
|
||||||
}
|
|
||||||
// TODO: Record the actual user that sent the suspension where possible
|
|
||||||
self.services
|
|
||||||
.users
|
|
||||||
.suspend_account(&user_id, self.sender_or_service_user())
|
|
||||||
.await;
|
|
||||||
|
|
||||||
self.write_str(&format!("User {user_id} has been suspended."))
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
#[admin_command]
|
|
||||||
pub(super) async fn unsuspend(&self, user_id: String) -> Result {
|
|
||||||
let user_id = parse_local_user_id(self.services, &user_id)?;
|
|
||||||
|
|
||||||
if user_id == self.services.globals.server_user {
|
|
||||||
return Err!("Not allowed to unsuspend the server service account.",);
|
|
||||||
}
|
|
||||||
|
|
||||||
if !self.services.users.exists(&user_id).await {
|
|
||||||
return Err!("User {user_id} does not exist.");
|
|
||||||
}
|
|
||||||
self.services.users.unsuspend_account(&user_id).await;
|
|
||||||
|
|
||||||
self.write_str(&format!("User {user_id} has been unsuspended."))
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
#[admin_command]
|
#[admin_command]
|
||||||
pub(super) async fn reset_password(&self, username: String, password: Option<String>) -> Result {
|
pub(super) async fn reset_password(&self, username: String, password: Option<String>) -> Result {
|
||||||
let user_id = parse_local_user_id(self.services, &username)?;
|
let user_id = parse_local_user_id(self.services, &username)?;
|
||||||
|
|
|
@ -59,28 +59,6 @@ pub(super) enum UserCommand {
|
||||||
force: bool,
|
force: bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// - Suspend a user
|
|
||||||
///
|
|
||||||
/// Suspended users are able to log in, sync, and read messages, but are not
|
|
||||||
/// able to send events nor redact them, cannot change their profile, and
|
|
||||||
/// are unable to join, invite to, or knock on rooms.
|
|
||||||
///
|
|
||||||
/// Suspended users can still leave rooms and deactivate their account.
|
|
||||||
/// Suspending them effectively makes them read-only.
|
|
||||||
Suspend {
|
|
||||||
/// Username of the user to suspend
|
|
||||||
user_id: String,
|
|
||||||
},
|
|
||||||
|
|
||||||
/// - Unsuspend a user
|
|
||||||
///
|
|
||||||
/// Reverses the effects of the `suspend` command, allowing the user to send
|
|
||||||
/// messages, change their profile, create room invites, etc.
|
|
||||||
Unsuspend {
|
|
||||||
/// Username of the user to unsuspend
|
|
||||||
user_id: String,
|
|
||||||
},
|
|
||||||
|
|
||||||
/// - List local users in the database
|
/// - List local users in the database
|
||||||
#[clap(alias = "list")]
|
#[clap(alias = "list")]
|
||||||
ListUsers,
|
ListUsers,
|
||||||
|
|
|
@ -18,9 +18,6 @@ pub(crate) async fn create_alias_route(
|
||||||
body: Ruma<create_alias::v3::Request>,
|
body: Ruma<create_alias::v3::Request>,
|
||||||
) -> Result<create_alias::v3::Response> {
|
) -> Result<create_alias::v3::Response> {
|
||||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||||
if services.users.is_suspended(sender_user).await? {
|
|
||||||
return Err!(Request(UserSuspended("You cannot perform this action while suspended.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
services
|
services
|
||||||
.rooms
|
.rooms
|
||||||
|
@ -66,9 +63,6 @@ pub(crate) async fn delete_alias_route(
|
||||||
body: Ruma<delete_alias::v3::Request>,
|
body: Ruma<delete_alias::v3::Request>,
|
||||||
) -> Result<delete_alias::v3::Response> {
|
) -> Result<delete_alias::v3::Response> {
|
||||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||||
if services.users.is_suspended(sender_user).await? {
|
|
||||||
return Err!(Request(UserSuspended("You cannot perform this action while suspended.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
services
|
services
|
||||||
.rooms
|
.rooms
|
||||||
|
|
|
@ -128,9 +128,6 @@ pub(crate) async fn set_room_visibility_route(
|
||||||
// Return 404 if the room doesn't exist
|
// Return 404 if the room doesn't exist
|
||||||
return Err!(Request(NotFound("Room not found")));
|
return Err!(Request(NotFound("Room not found")));
|
||||||
}
|
}
|
||||||
if services.users.is_suspended(sender_user).await? {
|
|
||||||
return Err!(Request(UserSuspended("You cannot perform this action while suspended.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
if services
|
if services
|
||||||
.users
|
.users
|
||||||
|
|
|
@ -52,9 +52,6 @@ pub(crate) async fn create_content_route(
|
||||||
body: Ruma<create_content::v3::Request>,
|
body: Ruma<create_content::v3::Request>,
|
||||||
) -> Result<create_content::v3::Response> {
|
) -> Result<create_content::v3::Response> {
|
||||||
let user = body.sender_user.as_ref().expect("user is authenticated");
|
let user = body.sender_user.as_ref().expect("user is authenticated");
|
||||||
if services.users.is_suspended(user).await? {
|
|
||||||
return Err!(Request(UserSuspended("You cannot perform this action while suspended.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
let filename = body.filename.as_deref();
|
let filename = body.filename.as_deref();
|
||||||
let content_type = body.content_type.as_deref();
|
let content_type = body.content_type.as_deref();
|
||||||
|
|
|
@ -182,9 +182,6 @@ pub(crate) async fn join_room_by_id_route(
|
||||||
body: Ruma<join_room_by_id::v3::Request>,
|
body: Ruma<join_room_by_id::v3::Request>,
|
||||||
) -> Result<join_room_by_id::v3::Response> {
|
) -> Result<join_room_by_id::v3::Response> {
|
||||||
let sender_user = body.sender_user();
|
let sender_user = body.sender_user();
|
||||||
if services.users.is_suspended(sender_user).await? {
|
|
||||||
return Err!(Request(UserSuspended("You cannot perform this action while suspended.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
banned_room_check(
|
banned_room_check(
|
||||||
&services,
|
&services,
|
||||||
|
@ -256,9 +253,6 @@ pub(crate) async fn join_room_by_id_or_alias_route(
|
||||||
let sender_user = body.sender_user.as_deref().expect("user is authenticated");
|
let sender_user = body.sender_user.as_deref().expect("user is authenticated");
|
||||||
let appservice_info = &body.appservice_info;
|
let appservice_info = &body.appservice_info;
|
||||||
let body = body.body;
|
let body = body.body;
|
||||||
if services.users.is_suspended(sender_user).await? {
|
|
||||||
return Err!(Request(UserSuspended("You cannot perform this action while suspended.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
let (servers, room_id) = match OwnedRoomId::try_from(body.room_id_or_alias) {
|
let (servers, room_id) = match OwnedRoomId::try_from(body.room_id_or_alias) {
|
||||||
| Ok(room_id) => {
|
| Ok(room_id) => {
|
||||||
|
@ -380,9 +374,6 @@ pub(crate) async fn knock_room_route(
|
||||||
) -> Result<knock_room::v3::Response> {
|
) -> Result<knock_room::v3::Response> {
|
||||||
let sender_user = body.sender_user();
|
let sender_user = body.sender_user();
|
||||||
let body = &body.body;
|
let body = &body.body;
|
||||||
if services.users.is_suspended(sender_user).await? {
|
|
||||||
return Err!(Request(UserSuspended("You cannot perform this action while suspended.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
let (servers, room_id) = match OwnedRoomId::try_from(body.room_id_or_alias.clone()) {
|
let (servers, room_id) = match OwnedRoomId::try_from(body.room_id_or_alias.clone()) {
|
||||||
| Ok(room_id) => {
|
| Ok(room_id) => {
|
||||||
|
@ -507,9 +498,6 @@ pub(crate) async fn invite_user_route(
|
||||||
body: Ruma<invite_user::v3::Request>,
|
body: Ruma<invite_user::v3::Request>,
|
||||||
) -> Result<invite_user::v3::Response> {
|
) -> Result<invite_user::v3::Response> {
|
||||||
let sender_user = body.sender_user();
|
let sender_user = body.sender_user();
|
||||||
if services.users.is_suspended(sender_user).await? {
|
|
||||||
return Err!(Request(UserSuspended("You cannot perform this action while suspended.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
if !services.users.is_admin(sender_user).await && services.config.block_non_admin_invites {
|
if !services.users.is_admin(sender_user).await && services.config.block_non_admin_invites {
|
||||||
debug_error!(
|
debug_error!(
|
||||||
|
@ -584,10 +572,6 @@ pub(crate) async fn kick_user_route(
|
||||||
State(services): State<crate::State>,
|
State(services): State<crate::State>,
|
||||||
body: Ruma<kick_user::v3::Request>,
|
body: Ruma<kick_user::v3::Request>,
|
||||||
) -> Result<kick_user::v3::Response> {
|
) -> Result<kick_user::v3::Response> {
|
||||||
let sender_user = body.sender_user();
|
|
||||||
if services.users.is_suspended(sender_user).await? {
|
|
||||||
return Err!(Request(UserSuspended("You cannot perform this action while suspended.")));
|
|
||||||
}
|
|
||||||
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
||||||
|
|
||||||
let Ok(event) = services
|
let Ok(event) = services
|
||||||
|
@ -623,7 +607,7 @@ pub(crate) async fn kick_user_route(
|
||||||
third_party_invite: None,
|
third_party_invite: None,
|
||||||
..event
|
..event
|
||||||
}),
|
}),
|
||||||
sender_user,
|
body.sender_user(),
|
||||||
&body.room_id,
|
&body.room_id,
|
||||||
&state_lock,
|
&state_lock,
|
||||||
)
|
)
|
||||||
|
@ -647,10 +631,6 @@ pub(crate) async fn ban_user_route(
|
||||||
return Err!(Request(Forbidden("You cannot ban yourself.")));
|
return Err!(Request(Forbidden("You cannot ban yourself.")));
|
||||||
}
|
}
|
||||||
|
|
||||||
if services.users.is_suspended(sender_user).await? {
|
|
||||||
return Err!(Request(UserSuspended("You cannot perform this action while suspended.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
||||||
|
|
||||||
let current_member_content = services
|
let current_member_content = services
|
||||||
|
@ -672,7 +652,6 @@ pub(crate) async fn ban_user_route(
|
||||||
is_direct: None,
|
is_direct: None,
|
||||||
join_authorized_via_users_server: None,
|
join_authorized_via_users_server: None,
|
||||||
third_party_invite: None,
|
third_party_invite: None,
|
||||||
redact_events: body.redact_events,
|
|
||||||
..current_member_content
|
..current_member_content
|
||||||
}),
|
}),
|
||||||
sender_user,
|
sender_user,
|
||||||
|
@ -693,10 +672,6 @@ pub(crate) async fn unban_user_route(
|
||||||
State(services): State<crate::State>,
|
State(services): State<crate::State>,
|
||||||
body: Ruma<unban_user::v3::Request>,
|
body: Ruma<unban_user::v3::Request>,
|
||||||
) -> Result<unban_user::v3::Response> {
|
) -> Result<unban_user::v3::Response> {
|
||||||
let sender_user = body.sender_user();
|
|
||||||
if services.users.is_suspended(sender_user).await? {
|
|
||||||
return Err!(Request(UserSuspended("You cannot perform this action while suspended.")));
|
|
||||||
}
|
|
||||||
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
||||||
|
|
||||||
let current_member_content = services
|
let current_member_content = services
|
||||||
|
@ -725,7 +700,7 @@ pub(crate) async fn unban_user_route(
|
||||||
is_direct: None,
|
is_direct: None,
|
||||||
..current_member_content
|
..current_member_content
|
||||||
}),
|
}),
|
||||||
sender_user,
|
body.sender_user(),
|
||||||
&body.room_id,
|
&body.room_id,
|
||||||
&state_lock,
|
&state_lock,
|
||||||
)
|
)
|
||||||
|
@ -956,32 +931,24 @@ pub async fn join_room_by_id_helper(
|
||||||
return Ok(join_room_by_id::v3::Response { room_id: room_id.into() });
|
return Ok(join_room_by_id::v3::Response { room_id: room_id.into() });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Ok(membership) = services
|
||||||
|
.rooms
|
||||||
|
.state_accessor
|
||||||
|
.get_member(room_id, sender_user)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
if membership.membership == MembershipState::Ban {
|
||||||
|
debug_warn!("{sender_user} is banned from {room_id} but attempted to join");
|
||||||
|
return Err!(Request(Forbidden("You are banned from the room.")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let server_in_room = services
|
let server_in_room = services
|
||||||
.rooms
|
.rooms
|
||||||
.state_cache
|
.state_cache
|
||||||
.server_in_room(services.globals.server_name(), room_id)
|
.server_in_room(services.globals.server_name(), room_id)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
// Only check our known membership if we're already in the room.
|
|
||||||
// See: https://forgejo.ellis.link/continuwuation/continuwuity/issues/855
|
|
||||||
let membership = if server_in_room {
|
|
||||||
services
|
|
||||||
.rooms
|
|
||||||
.state_accessor
|
|
||||||
.get_member(room_id, sender_user)
|
|
||||||
.await
|
|
||||||
} else {
|
|
||||||
debug!("Ignoring local state for join {room_id}, we aren't in the room yet.");
|
|
||||||
Ok(RoomMemberEventContent::new(MembershipState::Leave))
|
|
||||||
};
|
|
||||||
if let Ok(m) = membership {
|
|
||||||
if m.membership == MembershipState::Ban {
|
|
||||||
debug_warn!("{sender_user} is banned from {room_id} but attempted to join");
|
|
||||||
// TODO: return reason
|
|
||||||
return Err!(Request(Forbidden("You are banned from the room.")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let local_join = server_in_room
|
let local_join = server_in_room
|
||||||
|| servers.is_empty()
|
|| servers.is_empty()
|
||||||
|| (servers.len() == 1 && services.globals.server_is_ours(&servers[0]));
|
|| (servers.len() == 1 && services.globals.server_is_ours(&servers[0]));
|
||||||
|
@ -1858,7 +1825,6 @@ pub async fn leave_room(
|
||||||
displayname: None,
|
displayname: None,
|
||||||
third_party_invite: None,
|
third_party_invite: None,
|
||||||
blurhash: None,
|
blurhash: None,
|
||||||
redact_events: None,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_banned = services.rooms.metadata.is_banned(room_id);
|
let is_banned = services.rooms.metadata.is_banned(room_id);
|
||||||
|
|
|
@ -36,9 +36,6 @@ pub(crate) async fn set_displayname_route(
|
||||||
body: Ruma<set_display_name::v3::Request>,
|
body: Ruma<set_display_name::v3::Request>,
|
||||||
) -> Result<set_display_name::v3::Response> {
|
) -> Result<set_display_name::v3::Response> {
|
||||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||||
if services.users.is_suspended(sender_user).await? {
|
|
||||||
return Err!(Request(UserSuspended("You cannot perform this action while suspended.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
if *sender_user != body.user_id && body.appservice_info.is_none() {
|
if *sender_user != body.user_id && body.appservice_info.is_none() {
|
||||||
return Err!(Request(Forbidden("You cannot update the profile of another user")));
|
return Err!(Request(Forbidden("You cannot update the profile of another user")));
|
||||||
|
@ -128,9 +125,6 @@ pub(crate) async fn set_avatar_url_route(
|
||||||
body: Ruma<set_avatar_url::v3::Request>,
|
body: Ruma<set_avatar_url::v3::Request>,
|
||||||
) -> Result<set_avatar_url::v3::Response> {
|
) -> Result<set_avatar_url::v3::Response> {
|
||||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||||
if services.users.is_suspended(sender_user).await? {
|
|
||||||
return Err!(Request(UserSuspended("You cannot perform this action while suspended.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
if *sender_user != body.user_id && body.appservice_info.is_none() {
|
if *sender_user != body.user_id && body.appservice_info.is_none() {
|
||||||
return Err!(Request(Forbidden("You cannot update the profile of another user")));
|
return Err!(Request(Forbidden("You cannot update the profile of another user")));
|
||||||
|
@ -349,7 +343,6 @@ pub async fn update_displayname(
|
||||||
reason: None,
|
reason: None,
|
||||||
is_direct: None,
|
is_direct: None,
|
||||||
third_party_invite: None,
|
third_party_invite: None,
|
||||||
redact_events: None,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok((pdu, room_id))
|
Ok((pdu, room_id))
|
||||||
|
@ -403,7 +396,6 @@ pub async fn update_avatar_url(
|
||||||
reason: None,
|
reason: None,
|
||||||
is_direct: None,
|
is_direct: None,
|
||||||
third_party_invite: None,
|
third_party_invite: None,
|
||||||
redact_events: None,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok((pdu, room_id))
|
Ok((pdu, room_id))
|
||||||
|
|
|
@ -58,34 +58,29 @@ pub(crate) async fn set_read_marker_route(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(event) = &body.read_receipt {
|
if let Some(event) = &body.read_receipt {
|
||||||
if !services.users.is_suspended(sender_user).await? {
|
let receipt_content = BTreeMap::from_iter([(
|
||||||
let receipt_content = BTreeMap::from_iter([(
|
event.to_owned(),
|
||||||
event.to_owned(),
|
BTreeMap::from_iter([(
|
||||||
BTreeMap::from_iter([(
|
ReceiptType::Read,
|
||||||
ReceiptType::Read,
|
BTreeMap::from_iter([(sender_user.to_owned(), ruma::events::receipt::Receipt {
|
||||||
BTreeMap::from_iter([(
|
ts: Some(MilliSecondsSinceUnixEpoch::now()),
|
||||||
sender_user.to_owned(),
|
thread: ReceiptThread::Unthreaded,
|
||||||
ruma::events::receipt::Receipt {
|
})]),
|
||||||
ts: Some(MilliSecondsSinceUnixEpoch::now()),
|
)]),
|
||||||
thread: ReceiptThread::Unthreaded,
|
)]);
|
||||||
},
|
|
||||||
)]),
|
|
||||||
)]),
|
|
||||||
)]);
|
|
||||||
|
|
||||||
services
|
services
|
||||||
.rooms
|
.rooms
|
||||||
.read_receipt
|
.read_receipt
|
||||||
.readreceipt_update(
|
.readreceipt_update(
|
||||||
sender_user,
|
sender_user,
|
||||||
&body.room_id,
|
&body.room_id,
|
||||||
&ruma::events::receipt::ReceiptEvent {
|
&ruma::events::receipt::ReceiptEvent {
|
||||||
content: ruma::events::receipt::ReceiptEventContent(receipt_content),
|
content: ruma::events::receipt::ReceiptEventContent(receipt_content),
|
||||||
room_id: body.room_id.clone(),
|
room_id: body.room_id.clone(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(event) = &body.private_read_receipt {
|
if let Some(event) = &body.private_read_receipt {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use axum::extract::State;
|
use axum::extract::State;
|
||||||
use conduwuit::{Err, Result, matrix::pdu::PduBuilder};
|
use conduwuit::{Result, matrix::pdu::PduBuilder};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::client::redact::redact_event, events::room::redaction::RoomRedactionEventContent,
|
api::client::redact::redact_event, events::room::redaction::RoomRedactionEventContent,
|
||||||
};
|
};
|
||||||
|
@ -17,10 +17,6 @@ pub(crate) async fn redact_event_route(
|
||||||
) -> Result<redact_event::v3::Response> {
|
) -> Result<redact_event::v3::Response> {
|
||||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||||
let body = body.body;
|
let body = body.body;
|
||||||
if services.users.is_suspended(sender_user).await? {
|
|
||||||
// TODO: Users can redact their own messages while suspended
|
|
||||||
return Err!(Request(UserSuspended("You cannot perform this action while suspended.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
||||||
|
|
||||||
|
|
|
@ -70,10 +70,6 @@ pub(crate) async fn create_room_route(
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if services.users.is_suspended(sender_user).await? {
|
|
||||||
return Err!(Request(UserSuspended("You cannot perform this action while suspended.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
let room_id: OwnedRoomId = match &body.room_id {
|
let room_id: OwnedRoomId = match &body.room_id {
|
||||||
| Some(custom_room_id) => custom_room_id_check(&services, custom_room_id)?,
|
| Some(custom_room_id) => custom_room_id_check(&services, custom_room_id)?,
|
||||||
| _ => RoomId::new(&services.server.name),
|
| _ => RoomId::new(&services.server.name),
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::cmp::max;
|
||||||
|
|
||||||
use axum::extract::State;
|
use axum::extract::State;
|
||||||
use conduwuit::{
|
use conduwuit::{
|
||||||
Err, Error, Result, err, info,
|
Error, Result, err, info,
|
||||||
matrix::{StateKey, pdu::PduBuilder},
|
matrix::{StateKey, pdu::PduBuilder},
|
||||||
};
|
};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
|
@ -63,10 +63,6 @@ pub(crate) async fn upgrade_room_route(
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if services.users.is_suspended(sender_user).await? {
|
|
||||||
return Err!(Request(UserSuspended("You cannot perform this action while suspended.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a replacement room
|
// Create a replacement room
|
||||||
let replacement_room = RoomId::new(services.globals.server_name());
|
let replacement_room = RoomId::new(services.globals.server_name());
|
||||||
|
|
||||||
|
@ -193,7 +189,6 @@ pub(crate) async fn upgrade_room_route(
|
||||||
blurhash: services.users.blurhash(sender_user).await.ok(),
|
blurhash: services.users.blurhash(sender_user).await.ok(),
|
||||||
reason: None,
|
reason: None,
|
||||||
join_authorized_via_users_server: None,
|
join_authorized_via_users_server: None,
|
||||||
redact_events: None,
|
|
||||||
})
|
})
|
||||||
.expect("event is valid, we just created it"),
|
.expect("event is valid, we just created it"),
|
||||||
unsigned: None,
|
unsigned: None,
|
||||||
|
|
|
@ -23,9 +23,6 @@ pub(crate) async fn send_message_event_route(
|
||||||
let sender_user = body.sender_user();
|
let sender_user = body.sender_user();
|
||||||
let sender_device = body.sender_device.as_deref();
|
let sender_device = body.sender_device.as_deref();
|
||||||
let appservice_info = body.appservice_info.as_ref();
|
let appservice_info = body.appservice_info.as_ref();
|
||||||
if services.users.is_suspended(sender_user).await? {
|
|
||||||
return Err!(Request(UserSuspended("You cannot perform this action while suspended.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Forbid m.room.encrypted if encryption is disabled
|
// Forbid m.room.encrypted if encryption is disabled
|
||||||
if MessageLikeEventType::RoomEncrypted == body.event_type && !services.config.allow_encryption
|
if MessageLikeEventType::RoomEncrypted == body.event_type && !services.config.allow_encryption
|
||||||
|
|
|
@ -34,10 +34,6 @@ pub(crate) async fn send_state_event_for_key_route(
|
||||||
) -> Result<send_state_event::v3::Response> {
|
) -> Result<send_state_event::v3::Response> {
|
||||||
let sender_user = body.sender_user();
|
let sender_user = body.sender_user();
|
||||||
|
|
||||||
if services.users.is_suspended(sender_user).await? {
|
|
||||||
return Err!(Request(UserSuspended("You cannot perform this action while suspended.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(send_state_event::v3::Response {
|
Ok(send_state_event::v3::Response {
|
||||||
event_id: send_state_event_for_key_helper(
|
event_id: send_state_event_for_key_helper(
|
||||||
&services,
|
&services,
|
||||||
|
|
|
@ -26,42 +26,41 @@ pub(crate) async fn create_typing_event_route(
|
||||||
{
|
{
|
||||||
return Err!(Request(Forbidden("You are not in this room.")));
|
return Err!(Request(Forbidden("You are not in this room.")));
|
||||||
}
|
}
|
||||||
if !services.users.is_suspended(sender_user).await? {
|
|
||||||
match body.state {
|
match body.state {
|
||||||
| Typing::Yes(duration) => {
|
| Typing::Yes(duration) => {
|
||||||
let duration = utils::clamp(
|
let duration = utils::clamp(
|
||||||
duration.as_millis().try_into().unwrap_or(u64::MAX),
|
duration.as_millis().try_into().unwrap_or(u64::MAX),
|
||||||
services
|
|
||||||
.server
|
|
||||||
.config
|
|
||||||
.typing_client_timeout_min_s
|
|
||||||
.try_mul(1000)?,
|
|
||||||
services
|
|
||||||
.server
|
|
||||||
.config
|
|
||||||
.typing_client_timeout_max_s
|
|
||||||
.try_mul(1000)?,
|
|
||||||
);
|
|
||||||
services
|
services
|
||||||
.rooms
|
.server
|
||||||
.typing
|
.config
|
||||||
.typing_add(
|
.typing_client_timeout_min_s
|
||||||
sender_user,
|
.try_mul(1000)?,
|
||||||
&body.room_id,
|
|
||||||
utils::millis_since_unix_epoch()
|
|
||||||
.checked_add(duration)
|
|
||||||
.expect("user typing timeout should not get this high"),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
},
|
|
||||||
| _ => {
|
|
||||||
services
|
services
|
||||||
.rooms
|
.server
|
||||||
.typing
|
.config
|
||||||
.typing_remove(sender_user, &body.room_id)
|
.typing_client_timeout_max_s
|
||||||
.await?;
|
.try_mul(1000)?,
|
||||||
},
|
);
|
||||||
}
|
services
|
||||||
|
.rooms
|
||||||
|
.typing
|
||||||
|
.typing_add(
|
||||||
|
sender_user,
|
||||||
|
&body.room_id,
|
||||||
|
utils::millis_since_unix_epoch()
|
||||||
|
.checked_add(duration)
|
||||||
|
.expect("user typing timeout should not get this high"),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
},
|
||||||
|
| _ => {
|
||||||
|
services
|
||||||
|
.rooms
|
||||||
|
.typing
|
||||||
|
.typing_remove(sender_user, &body.room_id)
|
||||||
|
.await?;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// ping presence
|
// ping presence
|
||||||
|
|
|
@ -378,10 +378,6 @@ pub(super) static MAPS: &[Descriptor] = &[
|
||||||
name: "userid_password",
|
name: "userid_password",
|
||||||
..descriptor::RANDOM
|
..descriptor::RANDOM
|
||||||
},
|
},
|
||||||
Descriptor {
|
|
||||||
name: "userid_suspension",
|
|
||||||
..descriptor::RANDOM_SMALL
|
|
||||||
},
|
|
||||||
Descriptor {
|
Descriptor {
|
||||||
name: "userid_presenceid",
|
name: "userid_presenceid",
|
||||||
..descriptor::RANDOM_SMALL
|
..descriptor::RANDOM_SMALL
|
||||||
|
|
|
@ -44,13 +44,11 @@ struct Services {
|
||||||
services: StdRwLock<Option<Weak<crate::Services>>>,
|
services: StdRwLock<Option<Weak<crate::Services>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inputs to a command are a multi-line string, optional reply_id, and optional
|
/// Inputs to a command are a multi-line string and optional reply_id.
|
||||||
/// sender.
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CommandInput {
|
pub struct CommandInput {
|
||||||
pub command: String,
|
pub command: String,
|
||||||
pub reply_id: Option<OwnedEventId>,
|
pub reply_id: Option<OwnedEventId>,
|
||||||
pub sender: Option<Box<UserId>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prototype of the tab-completer. The input is buffered text when tab
|
/// Prototype of the tab-completer. The input is buffered text when tab
|
||||||
|
@ -163,22 +161,7 @@ impl Service {
|
||||||
pub fn command(&self, command: String, reply_id: Option<OwnedEventId>) -> Result<()> {
|
pub fn command(&self, command: String, reply_id: Option<OwnedEventId>) -> Result<()> {
|
||||||
self.channel
|
self.channel
|
||||||
.0
|
.0
|
||||||
.send(CommandInput { command, reply_id, sender: None })
|
.send(CommandInput { command, reply_id })
|
||||||
.map_err(|e| err!("Failed to enqueue admin command: {e:?}"))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Posts a command to the command processor queue with sender information
|
|
||||||
/// and returns. Processing will take place on the service worker's task
|
|
||||||
/// asynchronously. Errors if the queue is full.
|
|
||||||
pub fn command_with_sender(
|
|
||||||
&self,
|
|
||||||
command: String,
|
|
||||||
reply_id: Option<OwnedEventId>,
|
|
||||||
sender: Box<UserId>,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.channel
|
|
||||||
.0
|
|
||||||
.send(CommandInput { command, reply_id, sender: Some(sender) })
|
|
||||||
.map_err(|e| err!("Failed to enqueue admin command: {e:?}"))
|
.map_err(|e| err!("Failed to enqueue admin command: {e:?}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +172,7 @@ impl Service {
|
||||||
command: String,
|
command: String,
|
||||||
reply_id: Option<OwnedEventId>,
|
reply_id: Option<OwnedEventId>,
|
||||||
) -> ProcessorResult {
|
) -> ProcessorResult {
|
||||||
self.process_command(CommandInput { command, reply_id, sender: None })
|
self.process_command(CommandInput { command, reply_id })
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -532,11 +532,9 @@ impl Service {
|
||||||
self.services.search.index_pdu(shortroomid, &pdu_id, &body);
|
self.services.search.index_pdu(shortroomid, &pdu_id, &body);
|
||||||
|
|
||||||
if self.services.admin.is_admin_command(pdu, &body).await {
|
if self.services.admin.is_admin_command(pdu, &body).await {
|
||||||
self.services.admin.command_with_sender(
|
self.services
|
||||||
body,
|
.admin
|
||||||
Some((*pdu.event_id).into()),
|
.command(body, Some((*pdu.event_id).into()))?;
|
||||||
pdu.sender.clone().into(),
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -16,21 +16,10 @@ use ruma::{
|
||||||
},
|
},
|
||||||
serde::Raw,
|
serde::Raw,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::{Dep, account_data, admin, globals, rooms};
|
use crate::{Dep, account_data, admin, globals, rooms};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
pub struct UserSuspension {
|
|
||||||
/// Whether the user is currently suspended
|
|
||||||
pub suspended: bool,
|
|
||||||
/// When the user was suspended (Unix timestamp in milliseconds)
|
|
||||||
pub suspended_at: u64,
|
|
||||||
/// User ID of who suspended this user
|
|
||||||
pub suspended_by: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Service {
|
pub struct Service {
|
||||||
services: Services,
|
services: Services,
|
||||||
db: Data,
|
db: Data,
|
||||||
|
@ -63,7 +52,6 @@ struct Data {
|
||||||
userid_lastonetimekeyupdate: Arc<Map>,
|
userid_lastonetimekeyupdate: Arc<Map>,
|
||||||
userid_masterkeyid: Arc<Map>,
|
userid_masterkeyid: Arc<Map>,
|
||||||
userid_password: Arc<Map>,
|
userid_password: Arc<Map>,
|
||||||
userid_suspension: Arc<Map>,
|
|
||||||
userid_selfsigningkeyid: Arc<Map>,
|
userid_selfsigningkeyid: Arc<Map>,
|
||||||
userid_usersigningkeyid: Arc<Map>,
|
userid_usersigningkeyid: Arc<Map>,
|
||||||
useridprofilekey_value: Arc<Map>,
|
useridprofilekey_value: Arc<Map>,
|
||||||
|
@ -99,7 +87,6 @@ impl crate::Service for Service {
|
||||||
userid_lastonetimekeyupdate: args.db["userid_lastonetimekeyupdate"].clone(),
|
userid_lastonetimekeyupdate: args.db["userid_lastonetimekeyupdate"].clone(),
|
||||||
userid_masterkeyid: args.db["userid_masterkeyid"].clone(),
|
userid_masterkeyid: args.db["userid_masterkeyid"].clone(),
|
||||||
userid_password: args.db["userid_password"].clone(),
|
userid_password: args.db["userid_password"].clone(),
|
||||||
userid_suspension: args.db["userid_suspension"].clone(),
|
|
||||||
userid_selfsigningkeyid: args.db["userid_selfsigningkeyid"].clone(),
|
userid_selfsigningkeyid: args.db["userid_selfsigningkeyid"].clone(),
|
||||||
userid_usersigningkeyid: args.db["userid_usersigningkeyid"].clone(),
|
userid_usersigningkeyid: args.db["userid_usersigningkeyid"].clone(),
|
||||||
useridprofilekey_value: args.db["useridprofilekey_value"].clone(),
|
useridprofilekey_value: args.db["useridprofilekey_value"].clone(),
|
||||||
|
@ -156,23 +143,6 @@ impl Service {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Suspend account, placing it in a read-only state
|
|
||||||
pub async fn suspend_account(&self, user_id: &UserId, suspending_user: &UserId) {
|
|
||||||
self.db.userid_suspension.raw_put(
|
|
||||||
user_id,
|
|
||||||
Json(UserSuspension {
|
|
||||||
suspended: true,
|
|
||||||
suspended_at: MilliSecondsSinceUnixEpoch::now().get().into(),
|
|
||||||
suspended_by: suspending_user.to_string(),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Unsuspend account, placing it in a read-write state
|
|
||||||
pub async fn unsuspend_account(&self, user_id: &UserId) {
|
|
||||||
self.db.userid_suspension.remove(user_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if a user has an account on this homeserver.
|
/// Check if a user has an account on this homeserver.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub async fn exists(&self, user_id: &UserId) -> bool {
|
pub async fn exists(&self, user_id: &UserId) -> bool {
|
||||||
|
@ -189,25 +159,6 @@ impl Service {
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if account is suspended
|
|
||||||
pub async fn is_suspended(&self, user_id: &UserId) -> Result<bool> {
|
|
||||||
match self
|
|
||||||
.db
|
|
||||||
.userid_suspension
|
|
||||||
.get(user_id)
|
|
||||||
.await
|
|
||||||
.deserialized::<UserSuspension>()
|
|
||||||
{
|
|
||||||
| Ok(s) => Ok(s.suspended),
|
|
||||||
| Err(e) =>
|
|
||||||
if e.is_not_found() {
|
|
||||||
Ok(false)
|
|
||||||
} else {
|
|
||||||
Err(e)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if account is active, infallible
|
/// Check if account is active, infallible
|
||||||
pub async fn is_active(&self, user_id: &UserId) -> bool {
|
pub async fn is_active(&self, user_id: &UserId) -> bool {
|
||||||
!self.is_deactivated(user_id).await.unwrap_or(true)
|
!self.is_deactivated(user_id).await.unwrap_or(true)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue