1use std::sync::Arc;
3use base64::Engine as _;
4use base64::engine::general_purpose::STANDARD;
5use sha2::{Sha256, Digest};
6use chrono::Utc;
7use ed25519_dalek::{SigningKey, SecretKey, VerifyingKey};
8use rand::{rngs::OsRng, RngCore};
9use std::convert::TryFrom;
10use super::store::MeStore;
11use super::model::{Entry, GetFilter};
12
13pub struct Me<S: MeStore> {
14 pub username: String,
15 pub public_key: String,
16 pub context_id: String,
17 #[allow(dead_code)]
18 private_key_raw: String,
19 pub store: Arc<S>,
20}
21
22impl<S: MeStore> Me<S> {
23 pub fn with_store(username: String, public_key: String, private_key_raw: String, store: Arc<S>) -> Self {
24 let mut hasher = Sha256::new();
26 hasher.update(&private_key_raw);
27 let context_id = STANDARD.encode(hasher.finalize());
28
29 Self { username, public_key, context_id, private_key_raw, store }
30 }
31
32 pub async fn create(
33 store: Arc<S>,
34 username: &str,
35 password: &str,
36 ) -> Result<Self, Box<dyn std::error::Error + Send + Sync>> {
37 let mut csprng = OsRng {};
39 let mut secret_bytes = [0u8; 32];
40 csprng.fill_bytes(&mut secret_bytes);
41
42 let secret = SecretKey::try_from(&secret_bytes[..])
43 .map_err(|_| "Invalid secret key")?;
44 let signing_key = SigningKey::from(&secret);
45 let verify_key = VerifyingKey::from(&signing_key);
46
47 let public_key = STANDARD.encode(verify_key.to_bytes());
48 let private_key_raw = STANDARD.encode(signing_key.to_bytes()); let key = Self::derive_key(username, password)?;
52 let encoded_key = STANDARD.encode(&key);
53 let encrypted_binary = crate::utils::crypto::encrypt_string(&encoded_key, &private_key_raw)?;
54 let encrypted_private_key = STANDARD.encode(&encrypted_binary);
55
56 store.create_identity(username, &public_key, &encrypted_private_key).await?;
58
59 Ok(Self::with_store(
61 username.to_string(),
62 public_key,
63 private_key_raw,
64 store,
65 ))
66 }
67
68 pub async fn create_identity(store: Arc<S>, username: &str, encrypted_private_key: &str, public_key: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
69 store.create_identity(username, public_key, encrypted_private_key).await
70 }
71
72 pub async fn load(store: Arc<S>, username: &str, password: &str) -> Result<Self, Box<dyn std::error::Error + Send + Sync>> {
73 let (public_key, encrypted_private_key) = store.load_keys(username).await?;
75 let key = Self::derive_key(username, password)?;
77 let encoded_key = STANDARD.encode(&key);
78 let private_key_raw = crate::utils::crypto::decrypt_string(&encoded_key, &STANDARD.decode(encrypted_private_key)?)?;
79 Ok(Self::with_store(username.to_string(), public_key, private_key_raw, store))
80 }
81
82 pub async fn change_password(
83 &self,
84 new_password: &str,
85 ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
86 let key = Self::derive_key(&self.username, new_password)?;
87 let encoded_key = STANDARD.encode(&key);
88 let encrypted_binary = crate::utils::crypto::encrypt_string(&encoded_key, &self.private_key_raw)?;
89 let new_encrypted = STANDARD.encode(&encrypted_binary);
90
91 self.store
92 .update_encrypted_private(&self.username, &new_encrypted)
93 .await?;
94
95 Ok(())
96 }
97
98 fn derive_key(username: &str, password: &str) -> Result<Vec<u8>, Box<dyn std::error::Error + Send + Sync>> {
99 let mut hasher = Sha256::new();
100 hasher.update(username.as_bytes());
101 hasher.update(password.as_bytes());
102 Ok(hasher.finalize().to_vec())
103 }
104
105 pub async fn be(&self, context_id: &str, key: &str, value: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
107 self.insert("be", context_id, key, value).await
108 }
109 pub async fn have(&self, context_id: &str, key: &str, value: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
110 self.insert("have", context_id, key, value).await
111 }
112 pub async fn do_(&self, context_id: &str, key: &str, value: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
113 self.insert("do_", context_id, key, value).await
114 }
115 pub async fn at(&self, context_id: &str, key: &str, value: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
116 self.insert("at", context_id, key, value).await
117 }
118 pub async fn relate(&self, context_id: &str, key: &str, value: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
119 self.insert("relate", context_id, key, value).await
120 }
121 pub async fn react(&self, context_id: &str, key: &str, value: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
122 self.insert("react", context_id, key, value).await
123 }
124 pub async fn communicate(&self, context_id: &str, key: &str, value: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
125 self.insert("communicate", context_id, key, value).await
126 }
127
128 async fn insert(&self, verb: &str, context_id: &str, key: &str, value: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
129 let ts = Utc::now().to_rfc3339();
130 self.store.insert(verb, context_id, key, value, &ts).await
131 }
132
133 pub async fn get(&self, filter: &GetFilter) -> Result<Vec<Entry>, Box<dyn std::error::Error + Send + Sync>> {
134 self.store.get(filter).await
135 }
136}