Skip to content

Commit f978b22

Browse files
committed
Mint a fresh peer when the user changes
1 parent 85ae9cf commit f978b22

16 files changed

Lines changed: 206 additions & 65 deletions

File tree

‎document/format/src/error.rs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,8 @@ pub enum Error {
5858
#[cfg(feature = "network")]
5959
#[error("network error: {0}")]
6060
Network(#[from] peer_transport::PacketError),
61+
/// The user cannot change while the document is in its room, which knows this device by its peer.
62+
#[cfg(feature = "network")]
63+
#[error("the user cannot change while the document is connected")]
64+
UserChangeWhileConnected,
6165
}

‎document/format/src/lib.rs‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,10 @@ impl<L: Layout + Default> Gdd<L> {
175175

176176
/// Create a fresh, empty working copy at `path` bound to `peer`. Writes a default manifest
177177
/// and session state; the caller fills in editor metadata via [`Gdd::update_manifest`].
178-
pub fn create(path: &Path, peer: PeerId, document_uuid: u64, editor_version: String, stdlib_version: String) -> Result<Self, Error> {
178+
pub fn create(path: &Path, peer: PeerId, user: UserId, document_uuid: u64, editor_version: String, stdlib_version: String) -> Result<Self, Error> {
179179
let working = AnyContainer::Folder(FolderBackend::create(path)?);
180180
let layout = L::default();
181-
Self::create_in(working, layout, peer, document_uuid, editor_version, stdlib_version)
181+
Self::create_in(working, layout, peer, user, document_uuid, editor_version, stdlib_version)
182182
}
183183
}
184184

@@ -307,18 +307,18 @@ impl<L: Layout> Gdd<L> {
307307

308308
/// Backend-agnostic create. Records the working-copy default codecs (see `DEFAULT_*_CODEC`) in
309309
/// the manifest and writes each payload with its recorded codec.
310-
pub fn create_in(working: AnyContainer, layout: L, peer: PeerId, document_uuid: u64, editor_version: String, stdlib_version: String) -> Result<Self, Error> {
310+
pub fn create_in(working: AnyContainer, layout: L, peer: PeerId, user: UserId, document_uuid: u64, editor_version: String, stdlib_version: String) -> Result<Self, Error> {
311311
let manifest = Manifest::new(document_uuid, editor_version, stdlib_version);
312312
let codecs = manifest.codecs;
313313
io::write_single(&working, layout.manifest_basename(), MANIFEST_CODEC, &manifest)?;
314314
let session_state = SessionState {
315315
peer_id: peer,
316-
user_id: UserId(peer.0),
316+
user_id: user,
317317
..Default::default()
318318
};
319319
io::write_single(&working, layout.session_basename(), codecs.session, &Sorted(&session_state))?;
320320

321-
let session = Session::with_peer(peer);
321+
let session = Session::with_identity(peer, user);
322322
io::write_single(&working, layout.registry_basename(), codecs.registry, &Sorted(session.registry()))?;
323323

324324
Ok(Self::assemble(session, working, layout, manifest, HistoryMetadata::default()))

‎document/format/src/persist.rs‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
use document_container::{AnyContainer, AsyncContainer};
77
#[cfg(feature = "conversion")]
88
use document_graph_storage::NodeMetadataSource;
9-
use document_graph_storage::{HistoryMetadata, HotOp, MetadataFact, RegistryDelta, Rev, Sorted, Subject, TimeStamp, Value, WallStamp};
9+
use document_graph_storage::{HistoryMetadata, HotOp, MetadataFact, PeerId, RegistryDelta, Rev, Sorted, Subject, TimeStamp, UserId, Value, WallStamp};
1010
#[cfg(feature = "conversion")]
1111
use graphene_resource::ResourceStorage;
1212

@@ -65,6 +65,22 @@ impl<L: Layout> Gdd<L> {
6565
Ok(rev)
6666
}
6767

68+
/// Set the person using this device. A change takes `peer`, an id never used before, so the steps the previous
69+
/// person made stay theirs. See [`Session::set_user`](document_graph_storage::Session::set_user). Refused while
70+
/// connected.
71+
pub fn set_user(&mut self, user: UserId, peer: PeerId) -> Result<(), Error> {
72+
if self.session.user() == user {
73+
return Ok(());
74+
}
75+
#[cfg(feature = "network")]
76+
if self.network.is_some() {
77+
return Err(Error::UserChangeWhileConnected);
78+
}
79+
let closing = self.session.set_user(user, peer)?;
80+
self.persist_staged(&closing)?;
81+
self.persist_session_state()
82+
}
83+
6884
/// Edit the cached manifest and persist it. Always JSON, synchronous.
6985
pub fn update_manifest(&mut self, edit: impl FnOnce(&mut Manifest)) -> Result<(), Error> {
7086
edit(&mut self.manifest);

‎document/format/tests/deterministic_save.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use document_container::AnyContainer;
55
use document_container::backends::memory::MemoryBackend;
66
use document_format::{ExportFormat, ExportOptions, GddV1, GddV1Layout};
7-
use document_graph_storage::{Implementation, Network, NetworkId, Node, NodeId, PeerId, Priority, RegistryDelta, ResourceId, SourceKey, TimeStamp, to_value};
7+
use document_graph_storage::{Implementation, Network, NetworkId, Node, NodeId, PeerId, Priority, RegistryDelta, ResourceId, SourceKey, TimeStamp, UserId, to_value};
88
use graph_craft::application_io::resource::{HashMapResourceStorage, ResourceStorage};
99
use graphene_resource::DataSource;
1010
use std::collections::BTreeMap;
@@ -16,7 +16,7 @@ const LATEST: TimeStamp = TimeStamp {
1616
};
1717

1818
fn document(peer: u64) -> GddV1 {
19-
GddV1::create_in(AnyContainer::Memory(MemoryBackend::new()), GddV1Layout, PeerId(peer), 1, "editor".into(), "stdlib".into()).expect("create")
19+
GddV1::create_in(AnyContainer::Memory(MemoryBackend::new()), GddV1Layout, PeerId(peer), UserId(peer), 1, "editor".into(), "stdlib".into()).expect("create")
2020
}
2121

2222
/// Networks and nodes, some of each removed again, plus link-only resources whose bytes sit in the byte store.

‎document/format/tests/history_metadata.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const NOW_MS: f64 = 1_700_000_000_000.;
77
const ADA: Subject = Subject::User(UserId(10));
88

99
fn document(peer: u64) -> GddV1 {
10-
GddV1::create_in(AnyContainer::Memory(MemoryBackend::new()), GddV1Layout, PeerId(peer), 1, "editor".into(), "stdlib".into()).expect("create")
10+
GddV1::create_in(AnyContainer::Memory(MemoryBackend::new()), GddV1Layout, PeerId(peer), UserId(peer), 1, "editor".into(), "stdlib".into()).expect("create")
1111
}
1212

1313
/// Let the room settle through greetings, the sync handshake and whatever was broadcast.

‎document/format/tests/migration_recovery.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ fn network_of(nodes: &[(u64, &'static str)]) -> NodeNetwork {
3131
}
3232

3333
fn create() -> GddV1 {
34-
GddV1::create_in(AnyContainer::Memory(MemoryBackend::new()), GddV1Layout, PeerId(7), 1, "editor".into(), "std".into()).unwrap()
34+
GddV1::create_in(AnyContainer::Memory(MemoryBackend::new()), GddV1Layout, PeerId(7), UserId(7), 1, "editor".into(), "std".into()).unwrap()
3535
}
3636

3737
fn commit(gdd: &mut GddV1, nodes: &[(u64, &'static str)], store: &HashMapResourceStorage) {
@@ -79,7 +79,7 @@ fn a_migration_on_disk_leaves_no_staging_behind() {
7979
block_on(async {
8080
let directory = tempfile::tempdir().unwrap();
8181
let path = directory.path().join("document");
82-
let mut gdd = GddV1::create(&path, PeerId(7), 1, "editor".into(), "std".into()).unwrap();
82+
let mut gdd = GddV1::create(&path, PeerId(7), UserId(7), 1, "editor".into(), "std".into()).unwrap();
8383
commit(&mut gdd, &[(1, FADE)], &HashMapResourceStorage::new());
8484
drop(gdd);
8585

‎document/format/tests/migrations.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use document_container::AnyContainer;
55
use document_container::backends::memory::MemoryBackend;
66
use document_format::{Error, GddV1, GddV1Layout, manifest};
7-
use document_graph_storage::{EncodedDeclaration, Implementation, NoMetadata, PeerId};
7+
use document_graph_storage::{EncodedDeclaration, Implementation, NoMetadata, PeerId, UserId};
88
use futures::executor::block_on;
99
use graph_craft::application_io::resource::HashMapResourceStorage;
1010
use graph_craft::document::{DocumentNode, DocumentNodeImplementation, NodeId, NodeNetwork};
@@ -28,7 +28,7 @@ fn network_of(nodes: &[(u64, &'static str)]) -> NodeNetwork {
2828
}
2929

3030
fn create() -> GddV1 {
31-
GddV1::create_in(AnyContainer::Memory(MemoryBackend::new()), GddV1Layout, PeerId(7), 1, "editor".into(), "std".into()).unwrap()
31+
GddV1::create_in(AnyContainer::Memory(MemoryBackend::new()), GddV1Layout, PeerId(7), UserId(7), 1, "editor".into(), "std".into()).unwrap()
3232
}
3333

3434
fn implementations(gdd: &GddV1) -> Vec<Implementation> {

0 commit comments

Comments
 (0)