Development Documentation (main branch) - For stable release docs, see docs.rs/eidetica

User

Struct User 

Source
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

Source

pub fn user_uuid(&self) -> &str

Get the internal user UUID (stable identifier)

Source

pub fn username(&self) -> &str

Get the username (login identifier)

Source

pub fn user_database(&self) -> &Database

Get a reference to the user’s database

Source

pub fn backend(&self) -> &Backend

Get a reference to the backend

Source

pub fn user_info(&self) -> &UserInfo

Get a reference to the user info

Source

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.

Source

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)?;
Source

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:

  1. Finds an appropriate key that has access to the database
  2. Retrieves the decrypted SigningKey from the UserKeyManager
  3. Gets the SigKey mapping for this database
  4. 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
Source

pub async fn find_database( &self, name: impl AsRef<str>, ) -> Result<Vec<Database>>

Find databases by name among the user’s tracked databases.

Searches only the databases this user has tracked for those matching the given name.

§Arguments
  • name - Database name to search for
§Returns

Vector of matching databases from the user’s tracked list

Source

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

Source

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 identifier
  • database_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

Source

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 ID
  • sigkey - The SigKey identity to use for this database
§Errors

Returns an error if the key_id doesn’t exist in the user database

Source

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)

Source

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

Source

pub fn get_default_key(&self) -> Result<PublicKey>

Get the default key.

Returns the key marked as is_default=true, or falls back to the oldest key by creation timestamp if no default is explicitly set.

§Returns

The PublicKey of the default key

§Errors

Returns an error if no keys exist

Source

pub fn get_signing_key(&self, key_id: &PublicKey) -> Result<PrivateKey>

Get a signing key by its ID.

§Arguments
  • key_id - The public key identifier
§Returns

The PrivateKey if found

Source

pub async fn pending_bootstrap_requests( &self, sync: &Sync, ) -> Result<Vec<(String, BootstrapRequest)>>

Get all pending bootstrap requests from the sync system.

This is a convenience method that requires the Instance’s Sync to be initialized.

§Arguments
  • sync - Reference to the Instance’s Sync object
§Returns

A vector of (request_id, bootstrap_request) pairs for pending requests

Source

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 object
  • request_id - The unique identifier of the request to approve
  • approving_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
Source

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 object
  • request_id - The unique identifier of the request to reject
  • rejecting_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
Source

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 object
  • ticket - A ticket containing the database ID and address hints
  • key_id - The ID of this user’s key to use for the request
  • requested_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())?;
Source

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:

  1. Uses Database::find_sigkeys() to discover which SigKey the user can use
  2. Automatically selects the SigKey with highest permission
  3. 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 track
  • key_id - Which user key to use for this database
  • sync_settings - Sync preferences for this database
§Returns

Result indicating success or failure

§Errors
  • Returns NoSigKeyFound if no SigKey can be found for the specified key
  • Returns KeyNotFound if the specified key_id doesn’t exist
Source

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

Source

pub async fn database(&self, database_id: &ID) -> Result<TrackedDatabase>

Get a specific tracked database by ID.

§Arguments
  • database_id - The ID of the database
§Returns

The TrackedDatabase if it’s in the user’s tracked list

§Errors

Returns DatabaseNotTracked if the database is not in the user’s list

Source

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§

Source§

impl Debug for User

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for User

§

impl !RefUnwindSafe for User

§

impl Send for User

§

impl Sync for User

§

impl Unpin for User

§

impl !UnwindSafe for User

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> CompatExt for T

§

fn compat(self) -> Compat<T>

Applies the [Compat] adapter by value. Read more
§

fn compat_ref(&self) -> Compat<&T>

Applies the [Compat] adapter by shared reference. Read more
§

fn compat_mut(&mut self) -> Compat<&mut T>

Applies the [Compat] adapter by mutable reference. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more