systemprompt_users/repository/
device_cert.rs1use systemprompt_identifiers::{DeviceCertId, UserId};
2
3use crate::error::Result;
4use crate::models::UserDeviceCert;
5use crate::repository::UserRepository;
6
7pub struct EnrollDeviceCertParams<'a> {
8 pub id: &'a DeviceCertId,
9 pub user_id: &'a UserId,
10 pub fingerprint: &'a str,
11 pub label: &'a str,
12}
13
14impl UserRepository {
15 pub async fn enroll_device_cert(
16 &self,
17 params: EnrollDeviceCertParams<'_>,
18 ) -> Result<UserDeviceCert> {
19 let row = sqlx::query_as!(
20 UserDeviceCert,
21 r#"
22 INSERT INTO user_device_certs (id, user_id, fingerprint, label)
23 VALUES ($1, $2, $3, $4)
24 RETURNING id, user_id, fingerprint, label, enrolled_at, revoked_at
25 "#,
26 params.id.as_str(),
27 params.user_id.as_str(),
28 params.fingerprint,
29 params.label,
30 )
31 .fetch_one(&*self.write_pool)
32 .await?;
33 Ok(row)
34 }
35
36 pub async fn find_active_device_cert_by_fingerprint(
37 &self,
38 fingerprint: &str,
39 ) -> Result<Option<UserDeviceCert>> {
40 let row = sqlx::query_as!(
41 UserDeviceCert,
42 r#"
43 SELECT id, user_id, fingerprint, label, enrolled_at, revoked_at
44 FROM user_device_certs
45 WHERE fingerprint = $1 AND revoked_at IS NULL
46 "#,
47 fingerprint,
48 )
49 .fetch_optional(&*self.pool)
50 .await?;
51 Ok(row)
52 }
53
54 pub async fn list_device_certs_for_user(
55 &self,
56 user_id: &UserId,
57 ) -> Result<Vec<UserDeviceCert>> {
58 let rows = sqlx::query_as!(
59 UserDeviceCert,
60 r#"
61 SELECT id, user_id, fingerprint, label, enrolled_at, revoked_at
62 FROM user_device_certs
63 WHERE user_id = $1
64 ORDER BY enrolled_at DESC
65 "#,
66 user_id.as_str(),
67 )
68 .fetch_all(&*self.pool)
69 .await?;
70 Ok(rows)
71 }
72
73 pub async fn revoke_device_cert(&self, id: &DeviceCertId, user_id: &UserId) -> Result<bool> {
74 let result = sqlx::query!(
75 r#"
76 UPDATE user_device_certs
77 SET revoked_at = CURRENT_TIMESTAMP
78 WHERE id = $1 AND user_id = $2 AND revoked_at IS NULL
79 "#,
80 id.as_str(),
81 user_id.as_str(),
82 )
83 .execute(&*self.write_pool)
84 .await?;
85 Ok(result.rows_affected() > 0)
86 }
87}