Skip to main content

zlicenser_server/storage/
mod.rs

1pub 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}