zlicenser_server/storage/
mod.rs1pub mod types;
2pub use types::*;
3
4#[cfg(feature = "storage-sqlite")]
5pub mod sqlite;
6#[cfg(feature = "storage-sqlite")]
7pub use sqlite::SqliteStorage;
8
9#[cfg(feature = "storage-postgres")]
10pub mod postgres;
11#[cfg(feature = "storage-postgres")]
12pub use postgres::PostgresStorage;
13
14use async_trait::async_trait;
15use uuid::Uuid;
16
17#[async_trait]
18pub trait VendorStore: Send + Sync {
19 async fn get_vendor_config(&self) -> crate::Result<Option<VendorConfig>>;
20 async fn upsert_vendor_config(&self, config: &VendorConfig) -> crate::Result<()>;
21 async fn rotate_vendor_key(
22 &self,
23 new_public_key: &[u8],
24 new_fingerprint: &str,
25 rotated_from: &[u8],
26 rotated_at: i64,
27 ) -> crate::Result<()>;
28
29 async fn create_product(&self, p: &Product) -> crate::Result<()>;
30 async fn get_product(&self, id: Uuid) -> crate::Result<Option<Product>>;
31 async fn list_products(&self) -> crate::Result<Vec<Product>>;
32 async fn update_product(&self, p: &Product) -> crate::Result<()>;
33
34 async fn upsert_term_declaration(&self, d: &ProductTermDeclaration) -> crate::Result<()>;
35 async fn get_term_declaration(
36 &self,
37 product_id: Uuid,
38 ) -> crate::Result<Option<ProductTermDeclaration>>;
39
40 async fn create_terms_document(&self, d: &ProductTermsDocument) -> crate::Result<()>;
41 async fn get_terms_document(&self, id: Uuid) -> crate::Result<Option<ProductTermsDocument>>;
42 async fn get_active_terms_document(
43 &self,
44 product_id: Uuid,
45 ) -> crate::Result<Option<ProductTermsDocument>>;
46 async fn list_terms_documents(
47 &self,
48 product_id: Uuid,
49 ) -> crate::Result<Vec<ProductTermsDocument>>;
50 async fn update_terms_document_validation(
51 &self,
52 id: Uuid,
53 status: TermsValidationStatus,
54 findings: &str,
55 ) -> crate::Result<()>;
56 async fn acknowledge_terms_findings(
57 &self,
58 id: Uuid,
59 acknowledged_at: i64,
60 findings: &str,
61 ) -> crate::Result<()>;
62 async fn activate_terms_document(&self, id: Uuid, activated_at: i64) -> crate::Result<()>;
63
64 async fn replace_customer_fields(
65 &self,
66 product_id: Uuid,
67 fields: &[ProductCustomerField],
68 ) -> crate::Result<()>;
69 async fn get_customer_fields(
70 &self,
71 product_id: Uuid,
72 ) -> crate::Result<Vec<ProductCustomerField>>;
73
74 async fn create_upgrade_policy(&self, p: &UpgradePolicyRow) -> crate::Result<()>;
75 async fn get_upgrade_policy(&self, id: Uuid) -> crate::Result<Option<UpgradePolicyRow>>;
76 async fn find_upgrade_policy(
77 &self,
78 product_id: Uuid,
79 from_version: &str,
80 to_version: &str,
81 ) -> crate::Result<Option<UpgradePolicyRow>>;
82 async fn list_upgrade_policies(&self, product_id: Uuid)
83 -> crate::Result<Vec<UpgradePolicyRow>>;
84 async fn delete_upgrade_policy(&self, id: Uuid) -> crate::Result<()>;
85}
86
87#[async_trait]
88pub trait CustomerStore: Send + Sync {
89 async fn create_customer(&self, c: &Customer) -> crate::Result<()>;
90 async fn get_customer(&self, id: Uuid) -> crate::Result<Option<Customer>>;
91 async fn find_customer_by_email(
92 &self,
93 product_id: Uuid,
94 email: &str,
95 ) -> crate::Result<Option<Customer>>;
96 async fn update_customer(&self, c: &Customer) -> crate::Result<()>;
97}
98
99#[async_trait]
100pub trait LicenseStore: Send + Sync {
101 async fn create_license(&self, l: &License) -> crate::Result<()>;
102 async fn get_license(&self, id: Uuid) -> crate::Result<Option<License>>;
103 async fn list_licenses_for_customer(&self, customer_id: Uuid) -> crate::Result<Vec<License>>;
104 async fn update_license_status(
105 &self,
106 id: Uuid,
107 status: LicenseStatus,
108 revoked_at: Option<i64>,
109 revocation_reason: Option<&str>,
110 superseded_by: Option<Uuid>,
111 ) -> crate::Result<()>;
112 async fn update_license_email_sent(&self, id: Uuid, sent_at: i64) -> crate::Result<()>;
113
114 async fn create_consent_record(&self, r: &ConsentRecord) -> crate::Result<()>;
115 async fn get_consent_record(&self, id: Uuid) -> crate::Result<Option<ConsentRecord>>;
116 async fn get_consent_records_for_license(
117 &self,
118 license_id: Uuid,
119 ) -> crate::Result<Vec<ConsentRecord>>;
120}
121
122#[async_trait]
123pub trait SeatStore: Send + Sync {
124 async fn create_seat_binding(&self, b: &FingerprintSeatBinding) -> crate::Result<()>;
125 async fn get_seat_binding(&self, id: Uuid) -> crate::Result<Option<FingerprintSeatBinding>>;
126 async fn find_seat_binding_by_commitment(
127 &self,
128 license_id: Uuid,
129 commitment: &[u8],
130 ) -> crate::Result<Option<FingerprintSeatBinding>>;
131 async fn list_seat_bindings(
132 &self,
133 license_id: Uuid,
134 ) -> crate::Result<Vec<FingerprintSeatBinding>>;
135 async fn count_active_seat_bindings(&self, license_id: Uuid) -> crate::Result<u32>;
136 async fn revoke_seat_binding(&self, id: Uuid, revoked_at: i64) -> crate::Result<()>;
137 async fn update_seat_binding_verified(&self, id: Uuid, verified_at: i64) -> crate::Result<()>;
138
139 async fn create_issuance_secret(&self, s: &IssuanceSecret) -> crate::Result<()>;
140 async fn get_issuance_secret(&self, license_id: Uuid) -> crate::Result<Option<IssuanceSecret>>;
141 async fn delete_issuance_secret(&self, license_id: Uuid) -> crate::Result<()>;
142
143 async fn create_session(&self, s: &ActiveSession) -> crate::Result<()>;
144 async fn get_session(&self, id: Uuid) -> crate::Result<Option<ActiveSession>>;
145 async fn get_active_session_for_binding(
146 &self,
147 binding_id: Uuid,
148 ) -> crate::Result<Option<ActiveSession>>;
149 async fn update_session_heartbeat(
150 &self,
151 id: Uuid,
152 heartbeat_at: i64,
153 seq_no: i64,
154 ) -> crate::Result<()>;
155 async fn update_session_status(&self, id: Uuid, status: SessionStatus) -> crate::Result<()>;
156 async fn expire_sessions_before(&self, expires_at: i64) -> crate::Result<u64>;
157}
158
159#[async_trait]
160pub trait PaymentStore: Send + Sync {
161 async fn create_payment_transaction(&self, t: &PaymentTransaction) -> crate::Result<()>;
162 async fn get_payment_transaction(&self, id: Uuid) -> crate::Result<Option<PaymentTransaction>>;
163 async fn get_payment_transaction_for_license(
164 &self,
165 license_id: Uuid,
166 ) -> crate::Result<Option<PaymentTransaction>>;
167 async fn update_payment_status(
168 &self,
169 id: Uuid,
170 status: PaymentStatus,
171 confirmed_at: Option<i64>,
172 ) -> crate::Result<()>;
173
174 async fn create_transfer_request(&self, r: &TransferRequest) -> crate::Result<()>;
175 async fn get_transfer_request(&self, id: Uuid) -> crate::Result<Option<TransferRequest>>;
176 async fn list_transfer_requests_for_license(
177 &self,
178 license_id: Uuid,
179 ) -> crate::Result<Vec<TransferRequest>>;
180 async fn resolve_transfer_request(
181 &self,
182 id: Uuid,
183 status: TransferStatus,
184 vendor_note: Option<&str>,
185 resolved_at: i64,
186 ) -> crate::Result<()>;
187}
188
189#[async_trait]
190pub trait SecurityStore: Send + Sync {
191 async fn create_quarantine_case(&self, c: &QuarantineCase) -> crate::Result<()>;
192 async fn get_quarantine_case(&self, id: Uuid) -> crate::Result<Option<QuarantineCase>>;
193 async fn get_quarantine_case_by_case_id(
194 &self,
195 case_id: Uuid,
196 ) -> crate::Result<Option<QuarantineCase>>;
197 async fn resolve_quarantine_case(
198 &self,
199 id: Uuid,
200 status: QuarantineStatus,
201 resolution: Option<&str>,
202 resolved_at: i64,
203 vendor_note: Option<&str>,
204 ) -> crate::Result<()>;
205
206 async fn create_security_event(&self, e: &SecurityEvent) -> crate::Result<()>;
207 async fn get_security_events_for_license(
208 &self,
209 license_id: Uuid,
210 ) -> crate::Result<Vec<SecurityEvent>>;
211 async fn mark_security_event_reviewed(
212 &self,
213 id: i64,
214 reviewed_by: &str,
215 reviewed_at: i64,
216 ) -> crate::Result<()>;
217
218 async fn create_revocation_record(&self, r: &RevocationRecord) -> crate::Result<()>;
219 async fn get_revocation_record(
220 &self,
221 license_id: Uuid,
222 ) -> crate::Result<Option<RevocationRecord>>;
223
224 async fn create_email_log_entry(&self, e: &EmailLogEntry) -> crate::Result<()>;
225 async fn list_email_log_for_license(
226 &self,
227 license_id: Uuid,
228 ) -> crate::Result<Vec<EmailLogEntry>>;
229}
230
231#[async_trait]
232pub trait EnrollmentStore: Send + Sync {
233 async fn count_transferable_seat_bindings(&self, product_id: Uuid) -> crate::Result<u32>;
234 async fn set_seat_binding_transfer_pending(
235 &self,
236 id: Uuid,
237 pending_at: Option<i64>,
238 ) -> crate::Result<()>;
239 async fn create_enrollment_session(&self, s: &EnrollmentSession) -> crate::Result<()>;
240 async fn get_enrollment_session(&self, id: Uuid) -> crate::Result<Option<EnrollmentSession>>;
241 async fn get_session_by_payment_intent(
242 &self,
243 intent_id: &str,
244 ) -> crate::Result<Option<EnrollmentSession>>;
245 async fn update_enrollment_session(
246 &self,
247 id: Uuid,
248 expected_updated_at: i64,
249 update: EnrollmentSessionUpdate,
250 ) -> crate::Result<()>;
251 async fn list_grant_ready_sessions(&self) -> crate::Result<Vec<EnrollmentSession>>;
252}
253
254pub trait Storage:
255 VendorStore
256 + CustomerStore
257 + LicenseStore
258 + SeatStore
259 + PaymentStore
260 + SecurityStore
261 + EnrollmentStore
262{
263}
264
265impl<T> Storage for T where
266 T: VendorStore
267 + CustomerStore
268 + LicenseStore
269 + SeatStore
270 + PaymentStore
271 + SecurityStore
272 + EnrollmentStore
273{
274}