From 6d34d4b10ac8eb72e2d4ddc576a5de839585ccac Mon Sep 17 00:00:00 2001 From: Anna Date: Tue, 19 Jul 2022 18:09:23 -0400 Subject: [PATCH] feat: add option to disable invites --- server/src/handlers/allow_invites.rs | 13 +++++++++++++ server/src/handlers/authenticate.rs | 1 + server/src/handlers/invite.rs | 11 +++++++++-- server/src/handlers/mod.rs | 2 ++ server/src/handlers/public_key.rs | 21 ++++++++------------- server/src/main.rs | 9 +++++++++ server/src/types/protocol/allow_invites.rs | 11 +++++++++++ server/src/types/protocol/authenticate.rs | 7 +++++++ server/src/types/protocol/container.rs | 4 ++++ server/src/types/protocol/mod.rs | 2 ++ 10 files changed, 66 insertions(+), 15 deletions(-) create mode 100644 server/src/handlers/allow_invites.rs create mode 100644 server/src/types/protocol/allow_invites.rs diff --git a/server/src/handlers/allow_invites.rs b/server/src/handlers/allow_invites.rs new file mode 100644 index 0000000..3e7fc99 --- /dev/null +++ b/server/src/handlers/allow_invites.rs @@ -0,0 +1,13 @@ +use std::sync::Arc; + +use tokio::sync::RwLock; + +use crate::{ClientState, State, util, WsStream}; +use crate::types::protocol::{AllowInvitesRequest, AllowInvitesResponse}; + +pub async fn allow_invites(_state: Arc>, client_state: Arc>, conn: &mut WsStream, number: u32, req: AllowInvitesRequest) -> anyhow::Result<()> { + client_state.write().await.allow_invites = req.allowed; + util::send(conn, number, AllowInvitesResponse { + allowed: req.allowed, + }).await +} diff --git a/server/src/handlers/authenticate.rs b/server/src/handlers/authenticate.rs index a27ecdf..535d99c 100644 --- a/server/src/handlers/authenticate.rs +++ b/server/src/handlers/authenticate.rs @@ -69,6 +69,7 @@ pub async fn authenticate(state: Arc>, client_state: Arc>, client_state: Arc *id, - None => return crate::util::send(conn, number, ErrorResponse::new(req.channel, "user not online")).await, + None => return crate::util::send(conn, number, ErrorResponse::new(req.channel, NOT_ONLINE)).await, }; let target_id_i = target_id as i64; + if let Some(client) = state.read().await.clients.get(&target_id) { + if !client.read().await.allow_invites { + return crate::util::send(conn, number, ErrorResponse::new(req.channel, NOT_ONLINE)).await; + } + } + if target_id_i == lodestone_id { return crate::util::send(conn, number, ErrorResponse::new(req.channel, "cannot invite self")).await; } @@ -110,7 +117,7 @@ pub async fn invite(state: Arc>, client_state: Arc return crate::util::send(conn, number, ErrorResponse::new(req.channel, "user not online")).await, + None => return crate::util::send(conn, number, ErrorResponse::new(req.channel, NOT_ONLINE)).await, } crate::util::send(conn, number, InviteResponse { diff --git a/server/src/handlers/mod.rs b/server/src/handlers/mod.rs index 3a9d931..919c317 100644 --- a/server/src/handlers/mod.rs +++ b/server/src/handlers/mod.rs @@ -1,4 +1,5 @@ pub use self::{ + allow_invites::*, authenticate::*, create::*, disband::*, @@ -18,6 +19,7 @@ pub use self::{ version::*, }; +pub mod allow_invites; pub mod authenticate; pub mod create; pub mod disband; diff --git a/server/src/handlers/public_key.rs b/server/src/handlers/public_key.rs index fa34648..5d91140 100644 --- a/server/src/handlers/public_key.rs +++ b/server/src/handlers/public_key.rs @@ -10,25 +10,20 @@ use crate::util::redacted::Redacted; pub async fn public_key(state: Arc>, conn: &mut WsStream, number: u32, req: PublicKeyRequest) -> Result<()> { let id = match state.read().await.ids.get(&(req.name.clone(), req.world)) { Some(id) => *id, - None => { - crate::util::send(conn, number, PublicKeyResponse { - name: req.name, - world: req.world, - pk: None, - }).await?; - return Ok(()); - } + None => return crate::util::send(conn, number, PublicKeyResponse { + name: req.name, + world: req.world, + pk: None, + }).await, }; let pk = match state.read().await.clients.get(&id) { - Some(client) => Some(client.read().await.pk.clone()), - None => None, + Some(client) if client.read().await.allow_invites => Some(client.read().await.pk.clone()), + _ => None, }; crate::util::send(conn, number, PublicKeyResponse { name: req.name, world: req.world, pk: pk.map(Redacted), - }).await?; - - Ok(()) + }).await } diff --git a/server/src/main.rs b/server/src/main.rs index 06f0729..2feba7c 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -257,6 +257,7 @@ pub struct ClientState { user: Option, tx: Sender, pk: Vec, + allow_invites: bool, } impl ClientState { @@ -344,6 +345,7 @@ async fn client_loop(state: Arc>, mut conn: WsStream) -> Result<() user: None, tx, pk: Default::default(), + allow_invites: false, })); loop { @@ -422,6 +424,9 @@ async fn client_loop(state: Arc>, mut conn: WsStream) -> Result<() RequestKind::SendSecrets(req) if logged_in => { crate::handlers::send_secrets(Arc::clone(&state), Arc::clone(&client_state), &mut conn, msg.number, req).await?; } + RequestKind::AllowInvites(req) if logged_in => { + crate::handlers::allow_invites(Arc::clone(&state), Arc::clone(&client_state), &mut conn, msg.number, req).await?; + } _ if !logged_in => { util::send(&mut conn, msg.number, ErrorResponse::new(None, "not logged in")).await?; } @@ -446,10 +451,14 @@ async fn client_loop(state: Arc>, mut conn: WsStream) -> Result<() } } + debug!("ending client thread"); + if let Some(user) = &client_state.read().await.user { state.write().await.clients.remove(&user.lodestone_id); state.write().await.ids.remove(&(user.name.clone(), util::id_from_world(user.world))); } + debug!("client thread ended"); + Ok(()) } diff --git a/server/src/types/protocol/allow_invites.rs b/server/src/types/protocol/allow_invites.rs new file mode 100644 index 0000000..46ab712 --- /dev/null +++ b/server/src/types/protocol/allow_invites.rs @@ -0,0 +1,11 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AllowInvitesRequest { + pub allowed: bool, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AllowInvitesResponse { + pub allowed: bool, +} diff --git a/server/src/types/protocol/authenticate.rs b/server/src/types/protocol/authenticate.rs index fa71ace..9e85c6f 100644 --- a/server/src/types/protocol/authenticate.rs +++ b/server/src/types/protocol/authenticate.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; + use crate::util::redacted::Redacted; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -6,6 +7,8 @@ pub struct AuthenticateRequest { pub key: Redacted, #[serde(with = "serde_bytes")] pub pk: Redacted>, + #[serde(default = "default_true")] + pub allow_invites: bool, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -26,3 +29,7 @@ impl AuthenticateResponse { } } } + +fn default_true() -> bool { + true +} diff --git a/server/src/types/protocol/container.rs b/server/src/types/protocol/container.rs index ff2bbb2..0c943ff 100644 --- a/server/src/types/protocol/container.rs +++ b/server/src/types/protocol/container.rs @@ -28,6 +28,7 @@ pub enum RequestKind { PublicKey(PublicKeyRequest), Secrets(SecretsRequest), SendSecrets(SendSecretsRequest), + AllowInvites(AllowInvitesRequest), } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -61,6 +62,7 @@ pub enum ResponseKind { Secrets(SecretsResponse), SendSecrets(SendSecretsResponse), Announce(AnnounceResponse), + AllowInvites(AllowInvitesResponse), } macro_rules! request_container { @@ -90,6 +92,7 @@ request_container!(Update, UpdateRequest); request_container!(PublicKey, PublicKeyRequest); request_container!(Secrets, SecretsRequest); request_container!(SendSecrets, SendSecretsRequest); +request_container!(AllowInvites, AllowInvitesRequest); macro_rules! response_container { ($name:ident, $response:ty) => { @@ -123,3 +126,4 @@ response_container!(MemberChange, MemberChangeResponse); response_container!(Secrets, SecretsResponse); response_container!(SendSecrets, SendSecretsResponse); response_container!(Announce, AnnounceResponse); +response_container!(AllowInvites, AllowInvitesResponse); diff --git a/server/src/types/protocol/mod.rs b/server/src/types/protocol/mod.rs index bd09f91..bd08313 100644 --- a/server/src/types/protocol/mod.rs +++ b/server/src/types/protocol/mod.rs @@ -1,3 +1,4 @@ +pub mod allow_invites; pub mod announce; pub mod authenticate; pub mod container; @@ -22,6 +23,7 @@ pub mod version; pub mod channel; pub use self::{ + allow_invites::*, announce::*, authenticate::*, container::*,