From 5da26cb833171f8e86a3a223889a1c51b29d044d Mon Sep 17 00:00:00 2001 From: Paul <paulmakles@gmail.com> Date: Sat, 1 May 2021 15:54:29 +0100 Subject: [PATCH] Breaking: Provide new user object instead of id. Fix rustup complaining about join macros. --- .vscode/settings.json | 5 +++++ Cargo.lock | 2 +- Cargo.toml | 2 +- src/database/entities/user.rs | 16 ++++++++++++++++ src/database/permissions/mod.rs | 9 +++++++++ src/database/permissions/user.rs | 2 +- src/notifications/events.rs | 8 ++++---- src/routes/root.rs | 2 +- src/routes/users/add_friend.rs | 15 +++++++++++---- src/routes/users/block_user.rs | 28 +++++++++++++++++++--------- src/routes/users/remove_friend.rs | 14 ++++++++++---- src/routes/users/unblock_user.rs | 18 ++++++++++++------ 12 files changed, 90 insertions(+), 31 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b458b99 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "rust-analyzer.diagnostics.disabled": [ + "unresolved-macro-call" + ] +} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 612f500..20bc4ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2475,7 +2475,7 @@ dependencies = [ [[package]] name = "revolt" -version = "0.4.1-alpha.1" +version = "0.4.1-alpha.2" dependencies = [ "async-std", "async-tungstenite", diff --git a/Cargo.toml b/Cargo.toml index 0422bb7..ba34709 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt" -version = "0.4.1-alpha.1" +version = "0.4.1-alpha.2" authors = ["Paul Makles <paulmakles@gmail.com>"] edition = "2018" diff --git a/src/database/entities/user.rs b/src/database/entities/user.rs index e7c0e61..165e9a1 100644 --- a/src/database/entities/user.rs +++ b/src/database/entities/user.rs @@ -82,6 +82,8 @@ pub struct User { impl User { /// Mutate the user object to include relationship as seen by user. pub fn from(mut self, user: &User) -> User { + self.relationship = Some(RelationshipStatus::None); + if self.id == user.id { self.relationship = Some(RelationshipStatus::User); return self; @@ -102,12 +104,26 @@ impl User { pub fn with(mut self, permissions: UserPermissions<[u32; 1]>) -> User { if permissions.get_view_profile() { self.online = Some(is_online(&self.id)); + } else { + self.status = None; } self.profile = None; self } + /// Mutate the user object to appear as seen by user. + /// Also overrides the relationship status. + pub async fn from_override(mut self, user: &User, relationship: RelationshipStatus) -> Result<User> { + let permissions = PermissionCalculator::new(&user) + .with_relationship(&relationship) + .for_user(&self.id).await?; + + self.relations = None; + self.relationship = Some(relationship); + Ok(self.with(permissions)) + } + /// Utility function for checking claimed usernames. pub async fn is_username_taken(username: &str) -> Result<bool> { if username.to_lowercase() == "revolt" && username.to_lowercase() == "admin" { diff --git a/src/database/permissions/mod.rs b/src/database/permissions/mod.rs index 7fc9b26..6164478 100644 --- a/src/database/permissions/mod.rs +++ b/src/database/permissions/mod.rs @@ -9,6 +9,7 @@ pub struct PermissionCalculator<'a> { perspective: &'a User, user: Option<&'a User>, + relationship: Option<&'a RelationshipStatus>, channel: Option<&'a Channel>, has_mutual_connection: bool, @@ -20,6 +21,7 @@ impl<'a> PermissionCalculator<'a> { perspective, user: None, + relationship: None, channel: None, has_mutual_connection: false, @@ -33,6 +35,13 @@ impl<'a> PermissionCalculator<'a> { } } + pub fn with_relationship(self, relationship: &'a RelationshipStatus) -> PermissionCalculator { + PermissionCalculator { + relationship: Some(&relationship), + ..self + } + } + pub fn with_channel(self, channel: &'a Channel) -> PermissionCalculator { PermissionCalculator { channel: Some(&channel), diff --git a/src/database/permissions/user.rs b/src/database/permissions/user.rs index 7d516ee..f4d7c58 100644 --- a/src/database/permissions/user.rs +++ b/src/database/permissions/user.rs @@ -49,7 +49,7 @@ impl<'a> PermissionCalculator<'a> { } let mut permissions: u32 = 0; - match get_relationship(&self.perspective, &target) { + match self.relationship.clone().map(|v| v.to_owned()).unwrap_or_else(|| get_relationship(&self.perspective, &target)) { RelationshipStatus::Friend => return Ok(u32::MAX), RelationshipStatus::Blocked | RelationshipStatus::BlockedOther => { return Ok(UserPermission::Access as u32) diff --git a/src/notifications/events.rs b/src/notifications/events.rs index 4e92bdb..a71f0ae 100644 --- a/src/notifications/events.rs +++ b/src/notifications/events.rs @@ -80,8 +80,8 @@ pub enum ClientboundNotification { }, UserRelationship { id: String, - user: String, - status: RelationshipStatus, + user: User, + status: RelationshipStatus }, UserPresence { id: String, @@ -116,7 +116,7 @@ pub fn prehandle_hook(notification: &ClientboundNotification) { } ClientboundNotification::UserRelationship { id, user, status } => { if status != &RelationshipStatus::None { - subscribe_if_exists(id.clone(), user.clone()).ok(); + subscribe_if_exists(id.clone(), user.id.clone()).ok(); } } _ => {} @@ -132,7 +132,7 @@ pub fn posthandle_hook(notification: &ClientboundNotification) { if status == &RelationshipStatus::None { get_hive() .hive - .unsubscribe(&id.to_string(), &user.to_string()) + .unsubscribe(&id.to_string(), &user.id.to_string()) .ok(); } } diff --git a/src/routes/root.rs b/src/routes/root.rs index 1f2be02..669b08c 100644 --- a/src/routes/root.rs +++ b/src/routes/root.rs @@ -9,7 +9,7 @@ use rocket_contrib::json::JsonValue; #[get("/")] pub async fn root() -> JsonValue { json!({ - "revolt": "0.4.1-alpha.1", + "revolt": "0.4.1-alpha.2", "features": { "registration": !*DISABLE_REGISTRATION, "captcha": { diff --git a/src/routes/users/add_friend.rs b/src/routes/users/add_friend.rs index f918fc8..8d5cbef 100644 --- a/src/routes/users/add_friend.rs +++ b/src/routes/users/add_friend.rs @@ -31,6 +31,8 @@ pub async fn req(user: User, username: String) -> Result<JsonValue> { with: "user", })?; + let target_user = Ref::from(target_id.to_string())?.fetch_user().await?; + match get_relationship(&user, &target_id) { RelationshipStatus::User => return Err(Error::NoEffect), RelationshipStatus::Friend => return Err(Error::AlreadyFriends), @@ -65,16 +67,19 @@ pub async fn req(user: User, username: String) -> Result<JsonValue> { ) ) { Ok(_) => { + let target_user = target_user.from_override(&user, RelationshipStatus::Friend).await?; + let user = user.from_override(&target_user, RelationshipStatus::Friend).await?; + try_join!( ClientboundNotification::UserRelationship { id: user.id.clone(), - user: target_id.to_string(), + user: target_user, status: RelationshipStatus::Friend } .publish(user.id.clone()), ClientboundNotification::UserRelationship { id: target_id.to_string(), - user: user.id.clone(), + user, status: RelationshipStatus::Friend } .publish(target_id.to_string()) @@ -121,16 +126,18 @@ pub async fn req(user: User, username: String) -> Result<JsonValue> { ) ) { Ok(_) => { + let target_user = target_user.from_override(&user, RelationshipStatus::Outgoing).await?; + let user = user.from_override(&target_user, RelationshipStatus::Incoming).await?; try_join!( ClientboundNotification::UserRelationship { id: user.id.clone(), - user: target_id.to_string(), + user: target_user, status: RelationshipStatus::Outgoing } .publish(user.id.clone()), ClientboundNotification::UserRelationship { id: target_id.to_string(), - user: user.id.clone(), + user, status: RelationshipStatus::Incoming } .publish(target_id.to_string()) diff --git a/src/routes/users/block_user.rs b/src/routes/users/block_user.rs index 1fb5183..a554c28 100644 --- a/src/routes/users/block_user.rs +++ b/src/routes/users/block_user.rs @@ -10,6 +10,8 @@ use rocket_contrib::json::JsonValue; pub async fn req(user: User, target: Ref) -> Result<JsonValue> { let col = get_collection("users"); + let target = target.fetch_user().await?; + match get_relationship(&user, &target.id) { RelationshipStatus::User | RelationshipStatus::Blocked => Err(Error::NoEffect), RelationshipStatus::BlockedOther => { @@ -33,7 +35,7 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> { ClientboundNotification::UserRelationship { id: user.id.clone(), - user: target.id.clone(), + user: target, status: RelationshipStatus::Blocked, } .publish(user.id.clone()) @@ -74,19 +76,23 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> { ) ) { Ok(_) => { + let target = target.from_override(&user, RelationshipStatus::Friend).await?; + let user = user.from_override(&target, RelationshipStatus::Friend).await?; + let target_id = target.id.clone(); + try_join!( ClientboundNotification::UserRelationship { id: user.id.clone(), - user: target.id.clone(), + user: target, status: RelationshipStatus::Blocked } .publish(user.id.clone()), ClientboundNotification::UserRelationship { - id: target.id.clone(), - user: user.id.clone(), + id: target_id.clone(), + user, status: RelationshipStatus::BlockedOther } - .publish(target.id.clone()) + .publish(target_id) ) .ok(); @@ -128,19 +134,23 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> { ) ) { Ok(_) => { + let target = target.from_override(&user, RelationshipStatus::Blocked).await?; + let user = user.from_override(&target, RelationshipStatus::BlockedOther).await?; + let target_id = target.id.clone(); + try_join!( ClientboundNotification::UserRelationship { id: user.id.clone(), - user: target.id.clone(), + user: target, status: RelationshipStatus::Blocked } .publish(user.id.clone()), ClientboundNotification::UserRelationship { - id: target.id.clone(), - user: user.id.clone(), + id: target_id.clone(), + user, status: RelationshipStatus::BlockedOther } - .publish(target.id.clone()) + .publish(target_id) ) .ok(); diff --git a/src/routes/users/remove_friend.rs b/src/routes/users/remove_friend.rs index 37e831a..882594d 100644 --- a/src/routes/users/remove_friend.rs +++ b/src/routes/users/remove_friend.rs @@ -10,6 +10,8 @@ use rocket_contrib::json::JsonValue; pub async fn req(user: User, target: Ref) -> Result<JsonValue> { let col = get_collection("users"); + let target = target.fetch_user().await?; + match get_relationship(&user, &target.id) { RelationshipStatus::Friend | RelationshipStatus::Outgoing @@ -43,19 +45,23 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> { ) ) { Ok(_) => { + let target = target.from_override(&user, RelationshipStatus::None).await?; + let user = user.from_override(&target, RelationshipStatus::None).await?; + let target_id = target.id.clone(); + try_join!( ClientboundNotification::UserRelationship { id: user.id.clone(), - user: target.id.clone(), + user: target, status: RelationshipStatus::None } .publish(user.id.clone()), ClientboundNotification::UserRelationship { - id: target.id.clone(), - user: user.id.clone(), + id: target_id.clone(), + user, status: RelationshipStatus::None } - .publish(target.id.clone()) + .publish(target_id) ) .ok(); diff --git a/src/routes/users/unblock_user.rs b/src/routes/users/unblock_user.rs index ec575c4..8be4303 100644 --- a/src/routes/users/unblock_user.rs +++ b/src/routes/users/unblock_user.rs @@ -9,10 +9,11 @@ use rocket_contrib::json::JsonValue; #[delete("/<target>/block")] pub async fn req(user: User, target: Ref) -> Result<JsonValue> { let col = get_collection("users"); + let target = target.fetch_user().await?; match get_relationship(&user, &target.id) { RelationshipStatus::Blocked => { - match get_relationship(&target.fetch_user().await?, &user.id) { + match get_relationship(&target, &user.id) { RelationshipStatus::Blocked => { col.update_one( doc! { @@ -32,9 +33,10 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> { with: "user", })?; + let target = target.from_override(&user, RelationshipStatus::BlockedOther).await?; ClientboundNotification::UserRelationship { id: user.id.clone(), - user: target.id.clone(), + user: target, status: RelationshipStatus::BlockedOther, } .publish(user.id.clone()) @@ -73,19 +75,23 @@ pub async fn req(user: User, target: Ref) -> Result<JsonValue> { ) ) { Ok(_) => { + let target = target.from_override(&user, RelationshipStatus::None).await?; + let user = user.from_override(&target, RelationshipStatus::None).await?; + let target_id = target.id.clone(); + try_join!( ClientboundNotification::UserRelationship { id: user.id.clone(), - user: target.id.clone(), + user: target, status: RelationshipStatus::None } .publish(user.id.clone()), ClientboundNotification::UserRelationship { - id: target.id.clone(), - user: user.id.clone(), + id: target_id.clone(), + user: user, status: RelationshipStatus::None } - .publish(target.id.clone()) + .publish(target_id) ) .ok(); -- GitLab