1use chrono::Utc;
2use uuid::Uuid;
3
4use claw10_domain::{AgentId, Identity, IdentityId, IdentityKind, Permission};
5
6use crate::error::AuthError;
7
8pub struct IdentityService;
9
10impl IdentityService {
11 #[must_use]
12 pub fn create_agent_identity(agent_id: &AgentId) -> Identity {
13 Identity {
14 id: IdentityId(Uuid::now_v7()),
15 kind: IdentityKind::Agent,
16 name: format!("agent-{}", agent_id.0),
17 is_active: true,
18 created_at: Utc::now(),
19 updated_at: Utc::now(),
20 }
21 }
22
23 pub fn verify_permission(
24 identity: &Identity,
25 required: &Permission,
26 permissions: &[Permission],
27 ) -> Result<(), AuthError> {
28 if !identity.is_active {
29 return Err(AuthError::Unauthorized("identity is inactive".into()));
30 }
31
32 if !permissions.contains(required) {
33 let has: Vec<String> = permissions.iter().map(|p| p.0.clone()).collect();
34 return Err(AuthError::InsufficientPermissions {
35 required: vec![required.0.clone()],
36 has,
37 });
38 }
39
40 Ok(())
41 }
42
43 pub fn verify_permissions(
44 identity: &Identity,
45 required: &[Permission],
46 permissions: &[Permission],
47 ) -> Result<(), AuthError> {
48 for req in required {
49 Self::verify_permission(identity, req, permissions)?;
50 }
51 Ok(())
52 }
53}