feat(sync): include site permissions in snapshots

This commit is contained in:
2026-05-16 06:43:04 -04:00
parent d5e25345c5
commit 00d48a9286
6 changed files with 194 additions and 2 deletions
+1
View File
@@ -35,6 +35,7 @@ mod sync_context;
mod sync_notes;
mod sync_profiles;
mod sync_reading_list;
mod sync_site_permissions;
mod tab_group_order;
mod tab_groups;
mod tab_lifecycle;
@@ -28,6 +28,9 @@ impl BrowserCore {
for record in body.reading_list {
self.apply_reading_list_sync_record(record, &mut summary, &context)?;
}
for record in body.site_permissions {
self.apply_site_permission_sync_record(record, &mut summary, &context)?;
}
Ok(summary)
}
}
@@ -0,0 +1,53 @@
use ely_domain::{
SiteOrigin, SitePermissionDecision, SitePermissionEntry, SitePermissionFeature, SyncObjectKind,
SyncObjectPolicy,
};
use ely_sync_client::SyncClientError;
use super::{BrowserCore, sync::snapshot_schema_error, sync_context::SyncSnapshotApplyContext};
use crate::{sync_engine::SyncSnapshotApplySummary, sync_records::SitePermissionSyncRecord};
impl BrowserCore {
pub(crate) fn visible_site_permissions_for_sync(&self) -> Vec<&SitePermissionEntry> {
if self.sync_object_policy(SyncObjectKind::SitePermissions) == SyncObjectPolicy::Paused {
return Vec::new();
}
self.site_permissions
.iter()
.filter(|entry| self.profile_allows_cloud_sync(entry.profile_id()))
.collect()
}
pub(super) fn apply_site_permission_sync_record(
&mut self,
record: SitePermissionSyncRecord,
summary: &mut SyncSnapshotApplySummary,
context: &SyncSnapshotApplyContext,
) -> Result<(), SyncClientError> {
let profile_id = self.sync_profile_id(&record.profile_id, context)?;
let origin = SiteOrigin::parse(record.origin).map_err(snapshot_schema_error)?;
let feature =
SitePermissionFeature::parse(&record.feature).map_err(snapshot_schema_error)?;
let decision =
SitePermissionDecision::parse(&record.decision).map_err(snapshot_schema_error)?;
let existing_index = self.site_permissions.iter().position(|entry| {
entry.profile_id() == &profile_id
&& entry.origin() == &origin
&& entry.feature() == feature
});
let entry = SitePermissionEntry::new(profile_id, origin, feature, decision);
match existing_index {
Some(index) if self.site_permissions[index] == entry => summary.record_skipped(),
Some(index) => {
self.site_permissions[index] = entry;
summary.record_updated();
}
None => {
self.site_permissions.push(entry);
summary.record_imported();
}
}
Ok(())
}
}
+27 -1
View File
@@ -2,7 +2,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
use ely_domain::{
ArchivePolicy, BookmarkEntry, BrowserTab, NoteEntry, NoteTarget, Profile, ProfileKind,
ProfileSyncPolicy, ReadingListEntry, ReadingProgress, Space, TabFlags,
ProfileSyncPolicy, ReadingListEntry, ReadingProgress, SitePermissionEntry, Space, TabFlags,
};
use serde::{Deserialize, Serialize};
@@ -24,6 +24,8 @@ pub(crate) struct SyncSnapshotBody {
pub(crate) notes: Vec<NoteSyncRecord>,
#[serde(default)]
pub(crate) reading_list: Vec<ReadingListSyncRecord>,
#[serde(default)]
pub(crate) site_permissions: Vec<SitePermissionSyncRecord>,
}
impl SyncSnapshotBody {
@@ -74,6 +76,11 @@ impl SyncSnapshotBody {
)
})
.collect(),
site_permissions: core
.visible_site_permissions_for_sync()
.into_iter()
.map(SitePermissionSyncRecord::from_entry)
.collect(),
}
}
}
@@ -373,6 +380,25 @@ impl ReadingProgressSyncRecord {
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub(crate) struct SitePermissionSyncRecord {
pub(crate) profile_id: String,
pub(crate) origin: String,
pub(crate) feature: String,
pub(crate) decision: String,
}
impl SitePermissionSyncRecord {
fn from_entry(entry: &SitePermissionEntry) -> Self {
Self {
profile_id: entry.profile_id().as_str().to_string(),
origin: entry.origin().as_str().to_string(),
feature: entry.feature().as_str().to_string(),
decision: entry.decision().as_str().to_string(),
}
}
}
fn default_sync_enabled() -> bool {
true
}