Skip to main content

this_me/core/
me.rs

1//this.me/crate/src/core/me.rs
2use 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        // context_id derivado del private_key (como tenías)
25        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        // 1) Generar secret 32 bytes y llaves ed25519
38        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()); // en claro (base64)
49
50        // 2) Derivar clave y cifrar privada
51        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        // 3) Persistir en el store
57        store.create_identity(username, &public_key, &encrypted_private_key).await?;
58
59        // 4) Construir Me con context_id derivado de la privada
60        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        // 1) store.load_keys -> (public_key, encrypted_private_key)
74        let (public_key, encrypted_private_key) = store.load_keys(username).await?;
75        // 2) derivar clave y desencriptar (igual que en tu código actual)
76        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    // ----- Verbos -----
106    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}