diff --git a/Cargo.lock b/Cargo.lock index 20f7ed0..35aeac1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1733,6 +1733,14 @@ version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +[[package]] +name = "logos-account" +version = "0.1.0" +dependencies = [ + "crypto", + "libchat", +] + [[package]] name = "logos-chat" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index c1a2ee1..9fb99e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ resolver = "3" members = [ "bin/chat-cli", + "core/account", "core/conversations", "core/crypto", "core/double-ratchets", @@ -16,14 +17,15 @@ members = [ ] default-members = [ - "core/sqlite", + "core/account", "core/conversations", "core/crypto", "core/double-ratchets", - "core/storage", "core/integration_tests_core", - "crates/client", + "core/sqlite", + "core/storage", "crates/client-ffi", + "crates/client", ] [workspace.dependencies] diff --git a/core/account/Cargo.toml b/core/account/Cargo.toml new file mode 100644 index 0000000..5162bf2 --- /dev/null +++ b/core/account/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "logos-account" +version = "0.1.0" +edition = "2024" + +[features] +dev = [] + +[dependencies] +# Workspace dependencies (sorted) +crypto = { workspace = true } +libchat = { workspace = true } + +# External dependencies (sorted) diff --git a/core/account/README.md b/core/account/README.md new file mode 100644 index 0000000..7e615e2 --- /dev/null +++ b/core/account/README.md @@ -0,0 +1,23 @@ +# λAccount + +Logos(λ) Accounts are used to represent users across multiple services. + +An Account is a grouping of different entities used to describe a single User or entity in the Logos Ecosystem. + + +## Services Supported + +|Service | Supported | +|--------|-----------| +| [λChat](https://github.com/logos-messaging/logos-chat) | 🟢 | + +### `LogosAccount` + +Not Implemented + +### `TestLogosAccount` (`feature = "dev"`) + +A minimal implementation intended for development, testing, and CLI tooling. It accepts any string as the account ID and generates a fresh Ed25519 key pair on construction. State is not persisted — identity is lost on drop. + +**Do not use in production.** + diff --git a/core/account/src/account.rs b/core/account/src/account.rs new file mode 100644 index 0000000..016d9bc --- /dev/null +++ b/core/account/src/account.rs @@ -0,0 +1,42 @@ +use crypto::{Ed25519SigningKey, Ed25519VerifyingKey}; + +use libchat::{AccountId, IdentityProvider}; + +/// A Test Focused LogosAccount using a pre-defined identifier. +/// The test account is not persisted, and uses a single user provided id. +/// This account type should not be used in a production system. +pub struct TestLogosAccount { + id: AccountId, + signing_key: Ed25519SigningKey, + verifying_key: Ed25519VerifyingKey, +} + +impl TestLogosAccount { + pub fn new(explicit_id: impl Into) -> Self { + let signing_key = Ed25519SigningKey::generate(); + let verifying_key = signing_key.verifying_key(); + Self { + id: AccountId::new(explicit_id.into()), + signing_key, + verifying_key, + } + } +} + +impl IdentityProvider for TestLogosAccount { + fn account_id(&self) -> &AccountId { + &self.id + } + + fn display_name(&self) -> String { + self.id.to_string() + } + + fn public_key(&self) -> &Ed25519VerifyingKey { + &self.verifying_key + } + + fn sign(&self, payload: &[u8]) -> crypto::Ed25519Signature { + self.signing_key.sign(payload) + } +} diff --git a/core/account/src/lib.rs b/core/account/src/lib.rs new file mode 100644 index 0000000..c33c296 --- /dev/null +++ b/core/account/src/lib.rs @@ -0,0 +1,5 @@ +#[cfg(feature = "dev")] +mod account; + +#[cfg(feature = "dev")] +pub use account::TestLogosAccount; diff --git a/core/conversations/src/lib.rs b/core/conversations/src/lib.rs index b48e521..0d75124 100644 --- a/core/conversations/src/lib.rs +++ b/core/conversations/src/lib.rs @@ -16,6 +16,6 @@ pub use chat_sqlite::StorageConfig; pub use context::{Context, ConversationId, ConversationIdOwned, Introduction}; pub use conversation::GroupConvo; pub use errors::ChatError; -pub use service_traits::{DeliveryService, RegistrationService}; +pub use service_traits::{DeliveryService, IdentityProvider, RegistrationService}; pub use types::{AccountId, AddressedEnvelope, ContentData}; pub use utils::hex_trunc; diff --git a/core/conversations/src/service_traits.rs b/core/conversations/src/service_traits.rs index 669de34..391923d 100644 --- a/core/conversations/src/service_traits.rs +++ b/core/conversations/src/service_traits.rs @@ -3,6 +3,8 @@ /// different implementations. use std::{fmt::Debug, fmt::Display}; +use crypto::{Ed25519Signature, Ed25519VerifyingKey}; + use crate::types::{AccountId, AddressedEnvelope}; /// A Delivery service is responsible for payload transport. @@ -39,3 +41,14 @@ impl KeyPackageProvider for T { RegistrationService::retrieve(self, identity) } } + +/// Represents an external Identity +/// Implement this to provide an Authentication model for users/installations +pub trait IdentityProvider { + fn account_id(&self) -> &AccountId; + // Display name is not garenteed to be consistent. It should only be used to + // provded a more readable identifier for the account. + fn display_name(&self) -> String; + fn sign(&self, payload: &[u8]) -> Ed25519Signature; + fn public_key(&self) -> &Ed25519VerifyingKey; +}