From 44796283425893b89431e3a32663c79918c57f74 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 1 Dec 2023 11:41:38 -0800 Subject: [PATCH] Prevent moving a channel into its descendant --- crates/collab/src/db/queries/channels.rs | 7 +++++++ crates/collab/src/db/tests/channel_tests.rs | 14 ++++++++++++++ crates/collab2/src/db/queries/channels.rs | 7 +++++++ crates/collab2/src/db/tests/channel_tests.rs | 16 ++++++++++++++-- 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/crates/collab/src/db/queries/channels.rs b/crates/collab/src/db/queries/channels.rs index 68b06e435d..780fb783bc 100644 --- a/crates/collab/src/db/queries/channels.rs +++ b/crates/collab/src/db/queries/channels.rs @@ -1220,6 +1220,13 @@ impl Database { self.check_user_is_channel_admin(&new_parent, admin_id, &*tx) .await?; + if new_parent + .ancestors_including_self() + .any(|id| id == channel.id) + { + Err(anyhow!("cannot move a channel into one of its descendants"))?; + } + new_parent_path = new_parent.path(); new_parent_channel = Some(new_parent); } else { diff --git a/crates/collab/src/db/tests/channel_tests.rs b/crates/collab/src/db/tests/channel_tests.rs index 43526c7f24..324917bbdd 100644 --- a/crates/collab/src/db/tests/channel_tests.rs +++ b/crates/collab/src/db/tests/channel_tests.rs @@ -450,6 +450,20 @@ async fn test_db_channel_moving_bugs(db: &Arc) { (livestreaming_id, &[projects_id]), ], ); + + // Can't move a channel into its ancestor + db.move_channel(projects_id, Some(livestreaming_id), user_id) + .await + .unwrap_err(); + let result = db.get_channels_for_user(user_id).await.unwrap(); + assert_channel_tree( + result.channels, + &[ + (zed_id, &[]), + (projects_id, &[]), + (livestreaming_id, &[projects_id]), + ], + ); } test_both_dbs!( diff --git a/crates/collab2/src/db/queries/channels.rs b/crates/collab2/src/db/queries/channels.rs index 68b06e435d..780fb783bc 100644 --- a/crates/collab2/src/db/queries/channels.rs +++ b/crates/collab2/src/db/queries/channels.rs @@ -1220,6 +1220,13 @@ impl Database { self.check_user_is_channel_admin(&new_parent, admin_id, &*tx) .await?; + if new_parent + .ancestors_including_self() + .any(|id| id == channel.id) + { + Err(anyhow!("cannot move a channel into one of its descendants"))?; + } + new_parent_path = new_parent.path(); new_parent_channel = Some(new_parent); } else { diff --git a/crates/collab2/src/db/tests/channel_tests.rs b/crates/collab2/src/db/tests/channel_tests.rs index 43526c7f24..8a7a19ed3a 100644 --- a/crates/collab2/src/db/tests/channel_tests.rs +++ b/crates/collab2/src/db/tests/channel_tests.rs @@ -420,8 +420,6 @@ async fn test_db_channel_moving_bugs(db: &Arc) { .await .unwrap(); - // Dag is: zed - projects - livestreaming - // Move to same parent should be a no-op assert!(db .move_channel(projects_id, Some(zed_id), user_id) @@ -450,6 +448,20 @@ async fn test_db_channel_moving_bugs(db: &Arc) { (livestreaming_id, &[projects_id]), ], ); + + // Can't move a channel into its ancestor + db.move_channel(projects_id, Some(livestreaming_id), user_id) + .await + .unwrap_err(); + let result = db.get_channels_for_user(user_id).await.unwrap(); + assert_channel_tree( + result.channels, + &[ + (zed_id, &[]), + (projects_id, &[]), + (livestreaming_id, &[projects_id]), + ], + ); } test_both_dbs!(