eidetica/account/
signer.rs1use crate::{
4 Database, ID, Instance, Result,
5 auth::{SigKey, crypto::PublicKey},
6 database::DatabaseKey,
7};
8
9#[derive(Clone, Debug)]
17pub struct AccountSigner {
18 account_id: ID,
19 key: DatabaseKey,
20}
21
22impl AccountSigner {
23 pub fn new(account_id: ID, key: impl Into<DatabaseKey>) -> Self {
26 let (signer, mut identity) = key.into().into_parts();
27 if identity.hint().pubkey.is_none() {
30 identity.hint_mut().pubkey = Some(signer.public_key());
31 }
32 Self {
33 account_id,
34 key: DatabaseKey::with_identity(signer, identity),
35 }
36 }
37
38 pub(crate) fn signing_key(&self) -> &crate::auth::crypto::PrivateKey {
39 self.key.signing_key()
40 }
41
42 pub fn account_id(&self) -> &ID {
43 &self.account_id
44 }
45 pub fn key_id(&self) -> PublicKey {
46 self.key.public_key()
47 }
48 pub fn identity(&self) -> &SigKey {
49 self.key.identity()
50 }
51
52 pub fn with_identity(&self, identity: SigKey) -> Self {
55 Self::new(
56 self.account_id.clone(),
57 DatabaseKey::with_identity(self.key.signing_key().clone(), identity),
58 )
59 }
60
61 pub async fn connect(&self, url: impl AsRef<str>) -> Result<Instance> {
66 let instance = Instance::connect(url).await?;
67 #[cfg(all(unix, feature = "service"))]
68 if let Some(connection) = instance.remote_connection() {
69 connection
70 .authenticate_signer(self.key.signing_key())
71 .await?;
72 }
73 Ok(instance)
74 }
75
76 pub async fn open_account(&self, instance: &Instance) -> Result<super::Account> {
78 self.open_database(instance, &self.account_id)
79 .await
80 .map(super::Account::new)
81 }
82
83 pub async fn open_database(&self, instance: &Instance, root_id: &ID) -> Result<Database> {
86 if self.key.identity().hint().pubkey.as_ref() != Some(&self.key.public_key()) {
87 return Err(crate::auth::AuthError::InvalidAuthConfiguration {
88 reason: "Signer does not match the Auth identity public-key hint".to_owned(),
89 }
90 .into());
91 }
92 #[cfg(all(unix, feature = "service"))]
93 if let Some(connection) = instance.remote_connection() {
94 connection
95 .register_session_key(self.key.signing_key())
96 .await?;
97 return Ok(Database::open_remote(
98 instance,
99 connection.with_signer(self.key.signing_key().clone()),
100 root_id,
101 self.key.identity().clone(),
102 )
103 .await?
104 .with_key(self.key.clone()));
105 }
106 let database = Database::open(instance, root_id)
107 .await?
108 .with_key(self.key.clone());
109 database.current_permission().await?;
112 Ok(database)
113 }
114}