pub struct User { /* private fields */ }Expand description
User session object, returned after successful login
Represents an authenticated user with decrypted private keys loaded in memory. The User struct provides access to key management, tracked databases, and bootstrap approval operations.
Implementations§
Source§impl User
impl User
Sourcepub fn user_database(&self) -> &Database
pub fn user_database(&self) -> &Database
Get a reference to the user’s database
Sourcepub async fn is_admin(&self) -> Result<bool>
pub async fn is_admin(&self) -> Result<bool>
Whether this user is an instance admin.
“Instance admin” means the user’s default pubkey holds Admin in the
_users system database’s auth_settings. The admin/admin user
created during instance bootstrap is auto-promoted; subsequent users
land as non-admins until promoted via
InstanceAdmin::grant_instance_admin.
Returns false if the key resolution fails (key not in auth_settings,
non-Admin permission, etc.). For the capability handle rather than a
bool, use Self::admin.
Sourcepub async fn admin(&self) -> Result<InstanceAdmin<'_>>
pub async fn admin(&self) -> Result<InstanceAdmin<'_>>
Obtain the instance-admin capability view.
Returns an InstanceAdmin only if this user’s default key holds
Admin on the _users system database. All admin-gated operations
(creating users, listing users, promoting admins) live on the
returned view, so the privilege boundary is explicit at the call site
and those operations need no further permission check of their own.
§Errors
UserError::InsufficientPermissionsif this user is not an instance admin.
Sourcepub fn logout(self) -> Result<()>
pub fn logout(self) -> Result<()>
Logout (consumes self and clears decrypted keys from memory)
After logout, all decrypted keys are zeroized and the session is ended. Keys are automatically cleared when the User is dropped.
Sourcepub fn new_database(&mut self) -> DatabaseBuilder<'_>
pub fn new_database(&mut self) -> DatabaseBuilder<'_>
Start building a new database via the chainable DatabaseBuilder API.
The builder collects settings, key policy, and store initializers, then
produces a fully-initialized database in a single genesis entry when
DatabaseBuilder::build is called.
For the lower-level direct constructor see Self::create_database.
Sourcepub async fn create_database(
&mut self,
settings: Doc,
key_id: &PublicKey,
) -> Result<Database>
pub async fn create_database( &mut self, settings: Doc, key_id: &PublicKey, ) -> Result<Database>
Create a new database with explicit key selection.
This method requires you to specify which key should be used to create and manage the database, providing explicit control over key-database relationships.
§Arguments
settings- Initial database settings (metadata, name, etc.)key_id- The ID of the key to use for this database (public key string)
§Returns
The created Database
§Errors
- Returns an error if the specified key_id doesn’t exist
- Returns an error if the key cannot be retrieved
§Example
// Get available keys
let keys = user.list_keys()?;
let key_id = &keys[1]; // Use the second key
// Create database with explicit key selection
let mut settings = Doc::new();
settings.set("name", "My Database");
let database = user.new_database(settings, key_id)?;Sourcepub async fn create_database_with_init<F>(
&mut self,
settings: Doc,
key_id: &PublicKey,
init: F,
) -> Result<Database>
pub async fn create_database_with_init<F>( &mut self, settings: Doc, key_id: &PublicKey, init: F, ) -> Result<Database>
Creates a new database with an initialization callback that runs inside the genesis transaction.
This is the underlying constructor used by Self::create_database and by
Self::new_database (the builder API). The callback receives the
genesis transaction after _settings and _root have been staged but
before commit, allowing additional subtrees to be written into the same
entry that establishes the database root. See
Database::create_with_init for details on the atomicity guarantee.
After the genesis entry commits, this method performs the standard
user-side tracking write (key-database mapping, TrackedDatabase entry)
in a separate transaction on the user’s own system database.
Sourcepub async fn open_database(&self, root_id: &ID) -> Result<Database>
pub async fn open_database(&self, root_id: &ID) -> Result<Database>
Open an existing database by its root ID using this user’s keys.
This method automatically:
- Finds an appropriate key that has access to the database
- Retrieves the decrypted SigningKey from the UserKeyManager
- Gets the SigKey mapping for this database
- Creates a Database instance configured with the user’s key
The returned Database will use the user’s provided key for all operations, without requiring backend key lookups.
§Arguments
root_id- The root entry ID of the database
§Returns
The opened Database configured to use this user’s keys
§Errors
- Returns an error if no key is found for the database
- Returns an error if no SigKey mapping exists
- Returns an error if the key is not in the UserKeyManager
Sourcepub async fn open_database_with_key(
&self,
root_id: &ID,
key_id: &PublicKey,
) -> Result<Database>
pub async fn open_database_with_key( &self, root_id: &ID, key_id: &PublicKey, ) -> Result<Database>
Open an existing database with an explicitly chosen key.
Equivalent to open_database, but selects the user’s signing key by
public key instead of relying on find_key’s iteration order. Use this
when the user holds multiple authorized keys for a database and you
need writes signed by a specific one (e.g. agent-as-signer scenarios
where cryptographic provenance matters, not just authorization).
The key_id is purely a selector into this user’s UserKeyManager;
no crypto material is passed in.
§Arguments
root_id- The root entry ID of the databasekey_id- Public key of the user-held key to sign with
§Returns
The opened Database configured to use the specified key
§Errors
- Returns an error if the root entry does not exist
- Returns an error if the user does not hold a key with that pubkey
- Returns an error if the key has no SigKey mapping for this database
Sourcepub fn find_key(&self, database_id: &ID) -> Result<Option<PublicKey>>
pub fn find_key(&self, database_id: &ID) -> Result<Option<PublicKey>>
Find which key can access a database.
Searches this user’s keys to find one that can access the specified database. Considers the SigKey mappings stored in user key metadata.
Returns the key_id of a suitable key, preferring keys with mappings for this database.
§Arguments
database_id- The ID of the database
§Returns
Some(key_id) if a suitable key is found, None if no keys can access this database
Sourcepub fn key_mapping(
&self,
key_id: &PublicKey,
database_id: &ID,
) -> Result<Option<SigKey>>
pub fn key_mapping( &self, key_id: &PublicKey, database_id: &ID, ) -> Result<Option<SigKey>>
Get the resolved SigKey mapping for a key in a specific database.
Users map their private keys to SigKey identifiers on a per-database basis. This retrieves the resolved SigKey that a specific key uses in a specific database’s authentication settings.
Internally, None in the stored mapping means “default pubkey identity”,
which this method resolves to the concrete SigKey::from_pubkey(...) value.
§Arguments
key_id- The user’s key identifierdatabase_id- The database ID
§Returns
Ok(Some(sigkey)) if a mapping exists (resolved to concrete SigKey),
Ok(None) if no mapping is configured for this database
§Errors
Returns an error if the key_id doesn’t exist in the UserKeyManager
Sourcepub async fn map_key(
&mut self,
key_id: &PublicKey,
database_id: &ID,
sigkey: SigKey,
) -> Result<()>
pub async fn map_key( &mut self, key_id: &PublicKey, database_id: &ID, sigkey: SigKey, ) -> Result<()>
Map a key to a SigKey identity for a specific database.
Registers that this user’s key should be used with a specific SigKey identity when interacting with a database. This is typically used when a user has been granted access to a database and needs to configure their local key to work with it.
If the provided SigKey matches the default pubkey identity for this key,
it is normalized to None internally (compact storage for the common case).
§Multi-Key Support
Note: A database may have mappings to multiple keys. This is useful for multi-device scenarios where the same user wants to access a database from different devices, each with their own key.
§Arguments
key_id- The user’s key identifier (public key)database_id- The database IDsigkey- The SigKey identity to use for this database
§Errors
Returns an error if the key_id doesn’t exist in the user database
Sourcepub async fn add_private_key(
&mut self,
display_name: Option<&str>,
) -> Result<PublicKey>
pub async fn add_private_key( &mut self, display_name: Option<&str>, ) -> Result<PublicKey>
Add a new private key to this user’s keyring.
Generates a new Ed25519 keypair, encrypts it (for password-protected users) or stores it unencrypted (for passwordless users), and adds it to the user’s key database.
§Arguments
display_name- Optional display name for the key
§Returns
The key ID (public key string)
Sourcepub fn list_keys(&self) -> Result<Vec<PublicKey>>
pub fn list_keys(&self) -> Result<Vec<PublicKey>>
List all key IDs owned by this user.
Keys are returned sorted by creation timestamp (oldest first), making the first key in the list the “default” key created when the user was set up.
§Returns
Vector of PublicKeys sorted by creation time
Sourcepub fn get_default_key(&self) -> Result<PublicKey>
pub fn get_default_key(&self) -> Result<PublicKey>
Sourcepub fn key_display_name(&self, key_id: &PublicKey) -> Option<&str>
pub fn key_display_name(&self, key_id: &PublicKey) -> Option<&str>
Get the display name set for a key.
Display names are caller-supplied human-readable labels passed to
add_private_key. They have no cryptographic significance and are
not unique across keys. Returns None if the user does not hold a
key with this pubkey, or if it was added without a display name.
§Arguments
key_id- Public key of a key held by this user
Sourcepub fn find_keys_by_display_name(&self, name: &str) -> Vec<PublicKey>
pub fn find_keys_by_display_name(&self, name: &str) -> Vec<PublicKey>
Find user-held keys whose display name matches name.
Display names are not unique, so this returns every key whose
display_name exactly matches the provided string. Keys without a
display name are never returned. Returns an empty Vec when there
are no matches.
§Arguments
name- Exact display name to match
Sourcepub fn get_signing_key(&self, key_id: &PublicKey) -> Result<PrivateKey>
pub fn get_signing_key(&self, key_id: &PublicKey) -> Result<PrivateKey>
Sourcepub async fn pending_bootstrap_requests(
&self,
sync: &Sync,
) -> Result<Vec<(String, BootstrapRequest)>>
pub async fn pending_bootstrap_requests( &self, sync: &Sync, ) -> Result<Vec<(String, BootstrapRequest)>>
Sourcepub async fn approve_bootstrap_request(
&self,
sync: &Sync,
request_id: &str,
approving_key_id: &PublicKey,
) -> Result<()>
pub async fn approve_bootstrap_request( &self, sync: &Sync, request_id: &str, approving_key_id: &PublicKey, ) -> Result<()>
Approve a bootstrap request and add the requesting key to the target database.
The approving key must have Admin permission on the target database.
§Arguments
sync- Mutable reference to the Instance’s Sync objectrequest_id- The unique identifier of the request to approveapproving_key_id- The ID of this user’s key to use for approval (must have Admin permission)
§Returns
Result indicating success or failure of the approval operation
§Errors
- Returns an error if the user doesn’t own the specified approving key
- Returns an error if the approving key doesn’t have Admin permission on the target database
- Returns an error if the request doesn’t exist or isn’t pending
- Returns an error if the key addition to the database fails
Sourcepub async fn reject_bootstrap_request(
&self,
sync: &Sync,
request_id: &str,
rejecting_key_id: &PublicKey,
) -> Result<()>
pub async fn reject_bootstrap_request( &self, sync: &Sync, request_id: &str, rejecting_key_id: &PublicKey, ) -> Result<()>
Reject a bootstrap request.
This method marks the request as rejected. The requesting device will not be granted access to the target database. Requires Admin permission on the target database to prevent unauthorized users from disrupting the bootstrap protocol.
§Arguments
sync- Mutable reference to the Instance’s Sync objectrequest_id- The unique identifier of the request to rejectrejecting_key_id- The ID of this user’s key (for permission validation and audit trail)
§Returns
Result indicating success or failure of the rejection operation
§Errors
- Returns an error if the user doesn’t own the specified rejecting key
- Returns an error if the request doesn’t exist or isn’t pending
- Returns an error if the rejecting key lacks Admin permission on the target database
Sourcepub async fn request_database_access(
&self,
sync: &Sync,
ticket: &DatabaseTicket,
key_id: &PublicKey,
requested_permission: Permission,
) -> Result<()>
pub async fn request_database_access( &self, sync: &Sync, ticket: &DatabaseTicket, key_id: &PublicKey, requested_permission: Permission, ) -> Result<()>
Request access to a database from a peer (bootstrap sync).
This convenience method initiates a bootstrap sync request to access a database that this user doesn’t have locally yet. The user’s key will be sent to the peer to request the specified permission level.
This is useful for multi-device scenarios where a user wants to access their existing database from a new device, or when requesting access to a database shared by another user.
§Arguments
sync- Reference to the Instance’s Sync objectticket- A ticket containing the database ID and address hintskey_id- The ID of this user’s key to use for the requestrequested_permission- The permission level being requested
§Returns
Result indicating success or failure of the bootstrap request
§Errors
- Returns an error if the user doesn’t own the specified key
- Returns an error if all addresses in the ticket fail
- Returns an error if the bootstrap sync fails
§Example
// Request write access to a shared database
let user_key_id = user.get_default_key()?;
let ticket: DatabaseTicket = "eidetica:?db=sha256:abc...&pr=http:192.168.1.1:8080".parse()?;
user.request_database_access(
&sync,
&ticket,
&user_key_id,
Permission::Write(5),
).await?;
// After approval, the database can be opened
let database = user.open_database(ticket.database_id())?;Sourcepub async fn track_database(
&mut self,
database_id: impl Into<ID>,
key_id: &PublicKey,
sync_settings: SyncSettings,
) -> Result<()>
pub async fn track_database( &mut self, database_id: impl Into<ID>, key_id: &PublicKey, sync_settings: SyncSettings, ) -> Result<()>
Track a database, adding it to this user’s list with auto-discovery of SigKeys.
This method adds an existing database to your tracked list, or updates it if already tracked (upsert behavior).
When tracking:
- Uses Database::find_sigkeys() to discover which SigKey the user can use
- Automatically selects the SigKey with highest permission
- Stores the key mapping and sync settings
The sync_settings indicate your sync preferences, but do not automatically configure sync. Use the Sync module’s peer and tree methods to set up actual sync relationships.
§Arguments
database_id- ID of the database to trackkey_id- Which user key to use for this databasesync_settings- Sync preferences for this database
§Returns
Result indicating success or failure
§Errors
- Returns
NoSigKeyFoundif no SigKey can be found for the specified key - Returns
KeyNotFoundif the specified key_id doesn’t exist
Sourcepub async fn databases(&self) -> Result<Vec<TrackedDatabase>>
pub async fn databases(&self) -> Result<Vec<TrackedDatabase>>
List all tracked databases.
Returns all databases this user has added to their tracked list.
§Returns
Vector of TrackedDatabase entries
Sourcepub async fn database(&self, database_id: &ID) -> Result<TrackedDatabase>
pub async fn database(&self, database_id: &ID) -> Result<TrackedDatabase>
Sourcepub async fn enable_sync(&mut self, database_id: &ID) -> Result<()>
pub async fn enable_sync(&mut self, database_id: &ID) -> Result<()>
Enable sync for a tracked database.
Sets sync_enabled = true on the user’s preference for this database,
preserving sync_on_commit, interval_seconds, and properties.
Propagates the change to the host-level combined sync state by
calling Sync::sync_user if sync is attached to the instance.
No-op if already enabled.
§Errors
Returns DatabaseNotTracked if the database is not in the user’s list.
Sourcepub async fn disable_sync(&mut self, database_id: &ID) -> Result<()>
pub async fn disable_sync(&mut self, database_id: &ID) -> Result<()>
Disable sync for a tracked database.
Sets sync_enabled = false on the user’s preference for this database,
preserving other sync settings. Propagates to the host via
Sync::sync_user if sync is attached.
The host-level combined state is OR’d across all users on the instance, so another user with sync enabled for the same database will keep the host serving it.
No-op if already disabled.
§Errors
Returns DatabaseNotTracked if the database is not in the user’s list.
Enable sync for a tracked database and return a DatabaseTicket
for handoff.
Equivalent to building a ticket via
Sync::create_ticket and then
calling Self::enable_sync, in a single call. The ticket carries the
database ID plus any peer addresses that the instance’s sync transports
are currently advertising; a peer that imports the ticket via
Sync::sync_with_ticket will be
able to fetch the database immediately.
All preconditions (sync attached, transport registered) are checked
before any user state is mutated, so a failed share() leaves the
user’s sync preference unchanged.
§Errors
SyncError::SyncNotEnabledif sync is not attached to the instance (callInstance::enable_syncfirst).SyncError::NoTransportEnabledif sync is attached but no transport has been registered.UserError::DatabaseNotTrackedif the database is not in the user’s tracked list.
Sourcepub async fn is_sync_enabled(&self, database_id: &ID) -> Result<bool>
pub async fn is_sync_enabled(&self, database_id: &ID) -> Result<bool>
Check whether this user has sync enabled for a tracked database.
Returns this user’s own preference, not the host’s combined state.
A false result means this user is not personally sharing the database;
another user on the same instance may still have sync enabled for it.
Returns Ok(false) for databases not tracked by this user.
Sourcepub async fn untrack_database(&mut self, database_id: &ID) -> Result<()>
pub async fn untrack_database(&mut self, database_id: &ID) -> Result<()>
Stop tracking a database.
This removes the database from the user’s tracked list. It does not delete the database itself, remove key mappings, or delete any data.
§Arguments
database_id- The ID of the database to stop tracking
§Errors
Returns DatabaseNotTracked if the database is not in the user’s list
Trait Implementations§
Auto Trait Implementations§
impl Freeze for User
impl !RefUnwindSafe for User
impl Send for User
impl Sync for User
impl Unpin for User
impl UnsafeUnpin for User
impl !UnwindSafe for User
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> CompatExt for T
impl<T> CompatExt for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more