saorsa_core/identity/
enhanced.rs

1// Copyright 2024 Saorsa Labs Limited
2//
3// This software is dual-licensed under:
4// - GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later)
5// - Commercial License
6//
7// For AGPL-3.0 license, see LICENSE-AGPL-3.0
8// For commercial licensing, contact: saorsalabs@gmail.com
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under these licenses is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
14//! Enhanced identity system with quantum threshold cryptography integration
15
16use crate::identity::manager::{IdentityManager, UserIdentity};
17use crate::quantum_crypto::ant_quic_integration::{
18    generate_ml_dsa_keypair, generate_ml_kem_keypair,
19};
20use crate::quantum_crypto::{CryptoCapabilities, QuantumPeerIdentity};
21use crate::threshold::{ParticipantInfo, ParticipantRole, ThresholdGroupManager};
22use serde::{Deserialize, Serialize};
23use std::collections::HashMap;
24use std::time::SystemTime;
25use thiserror::Error;
26
27/// Enhanced identity errors
28#[derive(Debug, Error)]
29pub enum EnhancedIdentityError {
30    #[error("Quantum crypto error: {0}")]
31    QuantumError(#[from] crate::quantum_crypto::QuantumCryptoError),
32
33    #[error("Threshold error: {0}")]
34    ThresholdError(#[from] crate::threshold::ThresholdError),
35
36    #[error("Organization error: {0}")]
37    OrganizationError(String),
38
39    #[error("Permission denied: {0}")]
40    PermissionDenied(String),
41
42    #[error("System time error: {0}")]
43    SystemTime(String),
44
45    #[error("Anyhow error: {0}")]
46    AnyhowError(#[from] anyhow::Error),
47}
48
49type Result<T> = std::result::Result<T, EnhancedIdentityError>;
50
51/// Enhanced identity with quantum and threshold capabilities
52#[derive(Debug, Clone, Serialize, Deserialize)]
53pub struct EnhancedIdentity {
54    /// Base user identity (backward compatible)
55    pub base_identity: UserIdentity,
56
57    /// Quantum-resistant peer identity
58    pub quantum_identity: QuantumPeerIdentity,
59
60    /// Threshold groups this user belongs to
61    pub threshold_groups: Vec<GroupMembership>,
62
63    /// Organizations this user belongs to
64    pub organizations: Vec<OrganizationMembership>,
65
66    /// Device registry for multi-device support
67    pub devices: DeviceRegistry,
68
69    /// Last sync timestamp
70    pub last_sync: SystemTime,
71}
72
73/// Group membership information
74#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct GroupMembership {
76    pub group_id: crate::quantum_crypto::types::GroupId,
77    pub role: ParticipantRole,
78    pub joined_at: SystemTime,
79    pub permissions: Vec<Permission>,
80}
81
82/// Organization membership
83#[derive(Debug, Clone, Serialize, Deserialize)]
84pub struct OrganizationMembership {
85    pub org_id: OrganizationId,
86    pub department: Option<DepartmentId>,
87    pub team: Option<TeamId>,
88    pub role: OrganizationRole,
89    pub joined_at: SystemTime,
90}
91
92/// Organization identifier
93#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
94pub struct OrganizationId(pub String);
95
96/// Department identifier
97#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
98pub struct DepartmentId(pub String);
99
100/// Team identifier
101#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
102pub struct TeamId(pub String);
103
104/// Organization role
105#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
106pub enum OrganizationRole {
107    Owner,
108    Admin,
109    Manager,
110    Member,
111    Guest,
112}
113
114/// Permission types
115#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
116pub enum Permission {
117    // Chat permissions
118    ChatCreateChannel,
119    ChatDeleteChannel,
120    ChatInviteMembers,
121    ChatModerate,
122    ChatVoiceVideo,
123
124    // Discuss permissions
125    DiscussCreateCategory,
126    DiscussModerate,
127    DiscussPin,
128    DiscussWikiEdit,
129
130    // Project permissions
131    ProjectCreate,
132    ProjectDelete,
133    ProjectManageMembers,
134    ProjectUploadFiles,
135    ProjectApprove,
136
137    // Admin permissions
138    AdminManageRoles,
139    AdminViewAudit,
140    AdminManageOrg,
141}
142
143/// Device registry for multi-device support
144#[derive(Debug, Clone, Serialize, Deserialize)]
145pub struct DeviceRegistry {
146    /// Primary device ID (first device)
147    pub primary_device_id: DeviceId,
148
149    /// All registered devices
150    pub devices: HashMap<DeviceId, DeviceInfo>,
151
152    /// Device-specific keys (encrypted with master key)
153    pub device_keys: HashMap<DeviceId, EncryptedDeviceKey>,
154}
155
156/// Device identifier
157#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
158pub struct DeviceId(pub String);
159
160/// Device information
161#[derive(Debug, Clone, Serialize, Deserialize)]
162pub struct DeviceInfo {
163    pub name: String,
164    pub device_type: DeviceType,
165    pub last_seen: SystemTime,
166    pub added_at: SystemTime,
167    pub public_key: Vec<u8>,
168}
169
170/// Device type
171#[derive(Debug, Clone, Serialize, Deserialize)]
172pub enum DeviceType {
173    Desktop,
174    Mobile,
175    Tablet,
176    Web,
177}
178
179/// Encrypted device key
180#[derive(Debug, Clone, Serialize, Deserialize)]
181pub struct EncryptedDeviceKey {
182    pub encrypted_key: Vec<u8>,
183    pub nonce: Vec<u8>,
184}
185
186/// Organization structure
187#[derive(Debug, Clone, Serialize, Deserialize)]
188pub struct Organization {
189    pub id: OrganizationId,
190    pub name: String,
191    pub description: String,
192    pub root_group: crate::quantum_crypto::types::GroupId,
193    pub departments: Vec<Department>,
194    pub created_at: SystemTime,
195    pub settings: OrganizationSettings,
196}
197
198/// Department structure
199#[derive(Debug, Clone, Serialize, Deserialize)]
200pub struct Department {
201    pub id: DepartmentId,
202    pub name: String,
203    pub description: String,
204    pub manager_group: crate::quantum_crypto::types::GroupId,
205    pub teams: Vec<Team>,
206    pub parent_org: OrganizationId,
207}
208
209/// Team structure
210#[derive(Debug, Clone, Serialize, Deserialize)]
211pub struct Team {
212    pub id: TeamId,
213    pub name: String,
214    pub description: String,
215    pub lead_group: crate::quantum_crypto::types::GroupId,
216    pub member_group: crate::quantum_crypto::types::GroupId,
217    pub parent_dept: DepartmentId,
218}
219
220/// Organization settings
221#[derive(Debug, Clone, Serialize, Deserialize)]
222pub struct OrganizationSettings {
223    pub default_chat_encryption: bool,
224    pub require_2fa: bool,
225    pub session_timeout: std::time::Duration,
226    pub allowed_domains: Vec<String>,
227    pub features: OrganizationFeatures,
228}
229
230/// Organization features
231#[derive(Debug, Clone, Serialize, Deserialize)]
232pub struct OrganizationFeatures {
233    pub chat_enabled: bool,
234    pub discuss_enabled: bool,
235    pub projects_enabled: bool,
236    pub voice_video_enabled: bool,
237    pub ai_enabled: bool,
238}
239
240impl Default for OrganizationFeatures {
241    fn default() -> Self {
242        Self {
243            chat_enabled: true,
244            discuss_enabled: true,
245            projects_enabled: true,
246            voice_video_enabled: true,
247            ai_enabled: true,
248        }
249    }
250}
251
252/// Enhanced identity manager
253pub struct EnhancedIdentityManager {
254    /// Base identity manager
255    pub base_manager: IdentityManager,
256
257    /// Threshold group manager
258    pub group_manager: ThresholdGroupManager,
259
260    /// Organization registry
261    pub organizations: HashMap<OrganizationId, Organization>,
262}
263
264impl EnhancedIdentityManager {
265    /// Create new enhanced identity manager
266    pub fn new(base_manager: IdentityManager) -> Self {
267        // Create a temporary quantum identity for the group manager
268        let temp_quantum_identity = QuantumPeerIdentity {
269            peer_id: crate::quantum_crypto::types::PeerId(vec![0; 32]),
270            ml_dsa_public_key: vec![0; 32], // Placeholder Vec<u8>
271            ml_kem_public_key: vec![0; 32], // Placeholder Vec<u8>
272            frost_public_key: None,
273            legacy_key: None,
274            capabilities: CryptoCapabilities::default(),
275            created_at: SystemTime::now(),
276        };
277
278        Self {
279            base_manager,
280            group_manager: ThresholdGroupManager::new(temp_quantum_identity),
281            organizations: HashMap::new(),
282        }
283    }
284
285    /// Create enhanced identity from base identity
286    pub async fn create_enhanced_identity(
287        &mut self,
288        base_identity: UserIdentity,
289        device_name: String,
290        device_type: DeviceType,
291    ) -> Result<EnhancedIdentity> {
292        // Generate quantum-resistant keys
293        let capabilities = CryptoCapabilities::default();
294        // Generate PQC keys using ant-quic directly
295        let (_ml_dsa_pub, _ml_dsa_sec) = generate_ml_dsa_keypair()?;
296        let (_ml_kem_pub, _ml_kem_sec) = generate_ml_kem_keypair()?;
297
298        // Create quantum peer identity
299        let peer_id =
300            crate::quantum_crypto::types::PeerId(base_identity.user_id.as_bytes().to_vec());
301
302        let quantum_identity = QuantumPeerIdentity {
303            peer_id,
304            // NOTE: ant-quic PQC keys don't implement Serialize, using placeholder
305            // In production, implement proper serialization via ant-quic APIs
306            ml_dsa_public_key: vec![0u8; 1952], // ML-DSA-65 public key size
307            ml_kem_public_key: vec![0u8; 1184], // ML-KEM-768 public key size
308            frost_public_key: None,             // Optional threshold key
309            legacy_key: None,                   // Optional legacy key
310            capabilities,
311            created_at: SystemTime::now(),
312        };
313
314        // Update group manager with the new quantum identity
315        self.group_manager.local_identity = quantum_identity.clone();
316
317        // Create device registry
318        let device_id = DeviceId(format!(
319            "{}-{}",
320            base_identity.user_id,
321            SystemTime::now()
322                .duration_since(SystemTime::UNIX_EPOCH)
323                .map_err(|e| EnhancedIdentityError::SystemTime(format!(
324                    "System time error: {}",
325                    e
326                )))?
327                .as_secs()
328        ));
329
330        let device_info = DeviceInfo {
331            name: device_name,
332            device_type,
333            last_seen: SystemTime::now(),
334            added_at: SystemTime::now(),
335            public_key: vec![0u8; 32], // Placeholder - no legacy Ed25519 key for now
336        };
337
338        let mut devices = HashMap::new();
339        devices.insert(device_id.clone(), device_info);
340
341        let device_registry = DeviceRegistry {
342            primary_device_id: device_id,
343            devices,
344            device_keys: HashMap::new(),
345        };
346
347        Ok(EnhancedIdentity {
348            base_identity,
349            quantum_identity,
350            threshold_groups: Vec::new(),
351            organizations: Vec::new(),
352            devices: device_registry,
353            last_sync: SystemTime::now(),
354        })
355    }
356
357    /// Create new organization
358    pub async fn create_organization(
359        &mut self,
360        name: String,
361        description: String,
362        owner_identity: &EnhancedIdentity,
363    ) -> Result<Organization> {
364        // Create root threshold group for organization
365        let owner_info = ParticipantInfo {
366            participant_id: crate::quantum_crypto::types::ParticipantId(0),
367            public_key: owner_identity.quantum_identity.ml_dsa_public_key.clone(),
368            frost_share_commitment: crate::quantum_crypto::types::FrostCommitment(vec![0; 32]),
369            role: ParticipantRole::Leader {
370                permissions: crate::threshold::LeaderPermissions::default(),
371            },
372            status: crate::threshold::ParticipantStatus::Active,
373            joined_at: SystemTime::now(),
374            metadata: HashMap::new(),
375        };
376
377        let group_config = crate::threshold::GroupConfig {
378            threshold: 1,
379            participants: vec![owner_info],
380            metadata: crate::threshold::GroupMetadata {
381                name: format!("{name} Root Group"),
382                description: "Organization root authority".to_string(),
383                purpose: crate::threshold::GroupPurpose::Governance,
384                parent_group: None,
385                custom_data: HashMap::new(),
386            },
387        };
388
389        let root_group = self.group_manager.create_group(group_config).await?;
390
391        let org = Organization {
392            id: OrganizationId(uuid::Uuid::new_v4().to_string()),
393            name,
394            description,
395            root_group: root_group.group_id,
396            departments: Vec::new(),
397            created_at: SystemTime::now(),
398            settings: OrganizationSettings {
399                default_chat_encryption: true,
400                require_2fa: false,
401                session_timeout: std::time::Duration::from_secs(86400), // 24 hours
402                allowed_domains: Vec::new(),
403                features: OrganizationFeatures::default(),
404            },
405        };
406
407        self.organizations.insert(org.id.clone(), org.clone());
408
409        Ok(org)
410    }
411
412    /// Add user to organization
413    pub async fn add_user_to_organization(
414        &mut self,
415        user: &mut EnhancedIdentity,
416        org_id: &OrganizationId,
417        role: OrganizationRole,
418    ) -> Result<()> {
419        let _org = self.organizations.get(org_id).ok_or_else(|| {
420            EnhancedIdentityError::OrganizationError("Organization not found".to_string())
421        })?;
422
423        let membership = OrganizationMembership {
424            org_id: org_id.clone(),
425            department: None,
426            team: None,
427            role,
428            joined_at: SystemTime::now(),
429        };
430
431        user.organizations.push(membership);
432
433        Ok(())
434    }
435
436    /// Check permission for user in organization
437    pub fn check_permission(
438        &self,
439        user: &EnhancedIdentity,
440        org_id: &OrganizationId,
441        permission: Permission,
442    ) -> Result<()> {
443        let membership = user
444            .organizations
445            .iter()
446            .find(|m| &m.org_id == org_id)
447            .ok_or_else(|| {
448                EnhancedIdentityError::PermissionDenied("User not in organization".to_string())
449            })?;
450
451        // Check role-based permissions
452        let allowed = match (&membership.role, &permission) {
453            (OrganizationRole::Owner, _) => true,
454            (OrganizationRole::Admin, Permission::AdminManageOrg) => false,
455            (OrganizationRole::Admin, _) => true,
456            (OrganizationRole::Manager, Permission::AdminManageRoles) => false,
457            (OrganizationRole::Manager, Permission::AdminViewAudit) => false,
458            (OrganizationRole::Manager, Permission::AdminManageOrg) => false,
459            (OrganizationRole::Manager, _) => true,
460            (OrganizationRole::Member, perm) => matches!(
461                perm,
462                Permission::ChatCreateChannel
463                    | Permission::ChatInviteMembers
464                    | Permission::ChatVoiceVideo
465                    | Permission::DiscussWikiEdit
466                    | Permission::ProjectUploadFiles
467            ),
468            (OrganizationRole::Guest, perm) => matches!(perm, Permission::ChatVoiceVideo),
469        };
470
471        if allowed {
472            Ok(())
473        } else {
474            Err(EnhancedIdentityError::PermissionDenied(format!(
475                "Permission {:?} denied for role {:?}",
476                permission, membership.role
477            )))
478        }
479    }
480}