Trust settings sync as a collab project client (#46700)

Kirill Bulatov created

Collab projects are considered trusted and remote clients use the
editor-related settings only. A better fix would be sync "not trusted"
indicator with the project host, and disallow clients' iteraction with
that indicator.

Release Notes:

- Fixed collab settings sync causing "not trusted" pop ups for client

Change summary

crates/project/src/project.rs          |  2 ++
crates/project/src/project_settings.rs | 18 +++++++++++++++---
2 files changed, 17 insertions(+), 3 deletions(-)

Detailed changes

crates/project/src/project.rs 🔗

@@ -1355,6 +1355,7 @@ impl Project {
                     worktree_store.clone(),
                     task_store.clone(),
                     Some(remote_proto.clone()),
+                    false,
                     cx,
                 )
             });
@@ -1652,6 +1653,7 @@ impl Project {
                 worktree_store.clone(),
                 task_store.clone(),
                 None,
+                true,
                 cx,
             )
         });

crates/project/src/project_settings.rs 🔗

@@ -618,7 +618,7 @@ impl Settings for ProjectSettings {
 
 pub enum SettingsObserverMode {
     Local(Arc<dyn Fs>),
-    Remote,
+    Remote { via_collab: bool },
 }
 
 #[derive(Clone, Debug, PartialEq)]
@@ -739,6 +739,7 @@ impl SettingsObserver {
         worktree_store: Entity<WorktreeStore>,
         task_store: Entity<TaskStore>,
         upstream_client: Option<AnyProtoClient>,
+        via_collab: bool,
         cx: &mut Context<Self>,
     ) -> Self {
         let mut user_settings_watcher = None;
@@ -768,7 +769,7 @@ impl SettingsObserver {
         Self {
             worktree_store,
             task_store,
-            mode: SettingsObserverMode::Remote,
+            mode: SettingsObserverMode::Remote { via_collab },
             downstream_client: None,
             project_id: REMOTE_SERVER_PROJECT_ID,
             _trusted_worktrees_watcher: None,
@@ -845,6 +846,10 @@ impl SettingsObserver {
         };
         let path = RelPath::from_proto(&envelope.payload.path)?;
         this.update(&mut cx, |this, cx| {
+            let is_via_collab = match &this.mode {
+                SettingsObserverMode::Local(..) => false,
+                SettingsObserverMode::Remote { via_collab } => *via_collab,
+            };
             let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
             let Some(worktree) = this
                 .worktree_store
@@ -861,6 +866,7 @@ impl SettingsObserver {
                     local_settings_kind_from_proto(kind),
                     envelope.payload.content,
                 )],
+                is_via_collab,
                 cx,
             );
         });
@@ -1054,6 +1060,7 @@ impl SettingsObserver {
                         settings_contents.into_iter().map(|(path, kind, content)| {
                             (path, kind, content.and_then(|c| c.log_err()))
                         }),
+                        false,
                         cx,
                     )
                 })
@@ -1066,12 +1073,17 @@ impl SettingsObserver {
         &mut self,
         worktree: Entity<Worktree>,
         settings_contents: impl IntoIterator<Item = (Arc<RelPath>, LocalSettingsKind, Option<String>)>,
+        is_via_collab: bool,
         cx: &mut Context<Self>,
     ) {
         let worktree_id = worktree.read(cx).id();
         let remote_worktree_id = worktree.read(cx).id();
         let task_store = self.task_store.clone();
-        let can_trust_worktree = OnceCell::new();
+        let can_trust_worktree = if is_via_collab {
+            OnceCell::from(true)
+        } else {
+            OnceCell::new()
+        };
         for (directory, kind, file_content) in settings_contents {
             let mut applied = true;
             match kind {