Skip to main content

kellnr_db/
provider.rs

1use std::path::Path;
2
3use chrono::{DateTime, Utc};
4use crate_meta::CrateMeta;
5use kellnr_common::crate_data::CrateData;
6use kellnr_common::crate_overview::CrateOverview;
7use kellnr_common::cratesio_prefetch_msg::CratesioPrefetchMsg;
8use kellnr_common::index_metadata::IndexMetadata;
9use kellnr_common::normalized_name::NormalizedName;
10use kellnr_common::original_name::OriginalName;
11use kellnr_common::prefetch::Prefetch;
12use kellnr_common::publish_metadata::PublishMetadata;
13use kellnr_common::version::Version;
14use kellnr_common::webhook::{Webhook, WebhookEvent, WebhookQueue};
15use sea_orm::prelude::async_trait::async_trait;
16use serde::{Deserialize, Serialize};
17
18use crate::error::DbError;
19use crate::{AuthToken, CrateSummary, DocQueueEntry, Group, User, crate_meta};
20
21pub type DbResult<T> = Result<T, DbError>;
22
23#[derive(Debug, PartialEq, Eq)]
24pub enum PrefetchState {
25    /// The client's cached index is current. Carries the validators stored in
26    /// the database, which are the only ones that may be sent upstream.
27    UpToDate {
28        etag: String,
29        last_modified: String,
30    },
31    NeedsUpdate(Prefetch),
32    NotFound,
33}
34
35/// Which download-restricted crates a caller may see in crate listings.
36#[derive(Debug, Clone, PartialEq, Eq)]
37pub enum CrateVisibility {
38    /// All crates, used for admins.
39    All,
40    /// Unrestricted crates and the restricted crates the user owns or may
41    /// access as crate user or crate group member.
42    User(String),
43    /// Unrestricted crates only, used for anonymous callers.
44    Unrestricted,
45}
46
47/// Order of the crate overview list.
48#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, utoipa::ToSchema)]
49#[serde(rename_all = "lowercase")]
50pub enum CrateSort {
51    /// Alphabetical by name.
52    #[default]
53    Name,
54    /// Most recently updated first.
55    Updated,
56    /// Most downloaded first.
57    Downloads,
58}
59
60/// Restricts the crate overview list to crates with a keyword and/or a
61/// category. Both match case-insensitively and ignore crates.io proxy crates,
62/// which have neither.
63#[derive(Debug, Clone, Default, PartialEq, Eq)]
64pub struct CrateTagFilter {
65    pub keyword: Option<String>,
66    pub category: Option<String>,
67}
68
69impl CrateTagFilter {
70    pub fn is_empty(&self) -> bool {
71        self.keyword.is_none() && self.category.is_none()
72    }
73}
74
75/// Authenticated user and privileges resolved from a valid session cookie.
76#[derive(Debug, Clone, PartialEq, Eq)]
77pub struct SessionInfo {
78    pub name: String,
79    pub is_admin: bool,
80    pub is_read_only: bool,
81}
82
83/// Data stored during `OAuth2` authentication flow for CSRF/PKCE verification
84#[derive(Debug, Clone, PartialEq, Eq)]
85pub struct OAuth2StateData {
86    pub state: String,
87    pub pkce_verifier: String,
88    pub nonce: String,
89}
90
91/// Information about an individual toolchain component (e.g., rustc, cargo)
92#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, utoipa::ToSchema)]
93pub struct ToolchainComponentInfo {
94    /// Component name (e.g., "rustc", "cargo", "rust-std-x86_64-unknown-linux-gnu")
95    pub name: String,
96    /// Path to the stored component archive
97    pub storage_path: String,
98    /// SHA256 hash of the component archive
99    pub hash: String,
100    /// Component archive size in bytes
101    pub size: i64,
102}
103
104impl From<kellnr_entity::toolchain_component::Model> for ToolchainComponentInfo {
105    fn from(c: kellnr_entity::toolchain_component::Model) -> Self {
106        Self {
107            name: c.name,
108            storage_path: c.storage_path,
109            hash: c.hash,
110            size: c.size,
111        }
112    }
113}
114
115/// Toolchain target information (e.g., a specific archive for a target triple)
116#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, utoipa::ToSchema)]
117pub struct ToolchainTargetInfo {
118    /// Target ID
119    pub id: i64,
120    /// Target triple (e.g., "x86_64-unknown-linux-gnu")
121    pub target: String,
122    /// Path to the stored archive
123    pub storage_path: String,
124    /// SHA256 hash of the archive
125    pub hash: String,
126    /// Archive size in bytes
127    pub size: i64,
128    /// Processing status: "processing", "ready", or "failed"
129    pub status: String,
130    /// Individual components extracted from the combined archive
131    pub components: Vec<ToolchainComponentInfo>,
132}
133
134/// Toolchain with all its targets
135#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, utoipa::ToSchema)]
136pub struct ToolchainWithTargets {
137    /// Toolchain ID
138    pub id: i64,
139    /// Toolchain name (e.g., "rust")
140    pub name: String,
141    /// Toolchain version (e.g., "1.75.0")
142    pub version: String,
143    /// Release date
144    pub date: String,
145    /// Channel (e.g., "stable", "beta", "nightly")
146    pub channel: Option<String>,
147    /// Creation timestamp
148    pub created: String,
149    /// Available targets for this toolchain
150    pub targets: Vec<ToolchainTargetInfo>,
151}
152
153/// Channel information (e.g., "stable" -> "1.75.0")
154#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, utoipa::ToSchema)]
155pub struct ChannelInfo {
156    /// Channel name (e.g., "stable", "beta", "nightly")
157    pub name: String,
158    /// Toolchain version pointed to by this channel
159    pub version: String,
160    /// Release date
161    pub date: String,
162}
163
164#[async_trait]
165pub trait DbProvider: Send + Sync {
166    async fn get_last_updated_crate(
167        &self,
168        visibility: &CrateVisibility,
169    ) -> DbResult<Option<(OriginalName, Version)>>;
170    async fn authenticate_user(&self, name: &str, pwd: &str) -> DbResult<User>;
171    async fn increase_download_counter(
172        &self,
173        crate_name: &NormalizedName,
174        crate_version: &Version,
175    ) -> DbResult<()>;
176    async fn increase_cached_download_counter(
177        &self,
178        crate_name: &NormalizedName,
179        crate_version: &Version,
180    ) -> DbResult<()>;
181    async fn increase_download_counter_by(
182        &self,
183        crate_name: &NormalizedName,
184        crate_version: &Version,
185        count: u64,
186    ) -> DbResult<()>;
187    async fn increase_cached_download_counter_by(
188        &self,
189        crate_name: &NormalizedName,
190        crate_version: &Version,
191        count: u64,
192    ) -> DbResult<()>;
193    async fn validate_session(&self, session_token: &str) -> DbResult<SessionInfo>;
194    /// Delete all sessions that have outlived the configured session age.
195    /// Returns the number of rows removed.
196    async fn delete_expired_sessions(&self) -> DbResult<u64>;
197    async fn add_session_token(&self, name: &str, session_token: &str) -> DbResult<()>;
198    /// Delete all sessions of a user. Returns the number of rows removed.
199    async fn delete_user_sessions(&self, user_name: &str) -> DbResult<u64>;
200    /// Delete all sessions of a user except `keep_session_token`. Returns the
201    /// number of rows removed.
202    async fn delete_other_user_sessions(
203        &self,
204        user_name: &str,
205        keep_session_token: &str,
206    ) -> DbResult<u64>;
207    async fn add_crate_user(&self, crate_name: &NormalizedName, user: &str) -> DbResult<()>;
208    async fn add_owner(&self, crate_name: &NormalizedName, owner: &str) -> DbResult<()>;
209    async fn is_download_restricted(&self, crate_name: &NormalizedName) -> DbResult<bool>;
210    async fn change_download_restricted(
211        &self,
212        crate_name: &NormalizedName,
213        restricted: bool,
214    ) -> DbResult<()>;
215    async fn is_crate_user(&self, crate_name: &NormalizedName, user: &str) -> DbResult<bool>;
216    async fn is_owner(&self, crate_name: &NormalizedName, user: &str) -> DbResult<bool>;
217    async fn get_crate_id(&self, crate_name: &NormalizedName) -> DbResult<Option<i64>>;
218    async fn get_crate_owners(&self, crate_name: &NormalizedName) -> DbResult<Vec<User>>;
219    async fn get_crate_users(&self, crate_name: &NormalizedName) -> DbResult<Vec<User>>;
220    async fn get_crate_versions(&self, crate_name: &NormalizedName) -> DbResult<Vec<Version>>;
221    async fn delete_session_token(&self, session_token: &str) -> DbResult<()>;
222    async fn delete_user(&self, user_name: &str) -> DbResult<()>;
223    async fn change_pwd(&self, user_name: &str, new_pwd: &str) -> DbResult<()>;
224    async fn change_read_only_state(&self, user_name: &str, state: bool) -> DbResult<()>;
225    async fn change_admin_state(&self, user_name: &str, state: bool) -> DbResult<()>;
226    async fn crate_version_exists(&self, crate_id: i64, version: &str) -> DbResult<bool>;
227    async fn get_max_version_from_id(&self, crate_id: i64) -> DbResult<Version>;
228    async fn get_max_version_from_name(&self, crate_name: &NormalizedName) -> DbResult<Version>;
229    async fn update_max_version(&self, crate_id: i64, version: &Version) -> DbResult<()>;
230    async fn add_auth_token(&self, name: &str, token: &str, user: &str) -> DbResult<()>;
231    async fn get_user_from_token(&self, token: &str) -> DbResult<User>;
232    /// Name of the auth token, `None` if there is no such token.
233    async fn get_auth_token_name(&self, token: &str) -> DbResult<Option<String>>;
234    async fn get_user(&self, name: &str) -> DbResult<User>;
235    async fn get_auth_tokens(&self, user_name: &str) -> DbResult<Vec<AuthToken>>;
236    async fn delete_auth_token(&self, id: i32) -> DbResult<()>;
237    async fn delete_owner(&self, crate_name: &str, owner: &str) -> DbResult<()>;
238    async fn delete_crate_user(&self, crate_name: &NormalizedName, user: &str) -> DbResult<()>;
239    async fn add_user(
240        &self,
241        name: &str,
242        pwd: &str,
243        is_admin: bool,
244        is_read_only: bool,
245    ) -> DbResult<()>;
246    async fn get_users(&self) -> DbResult<Vec<User>>;
247    async fn add_group(&self, name: &str) -> DbResult<()>;
248    async fn get_group(&self, name: &str) -> DbResult<Group>;
249    async fn get_groups(&self) -> DbResult<Vec<Group>>;
250    async fn delete_group(&self, name: &str) -> DbResult<()>;
251    async fn add_group_user(&self, group_name: &str, user: &str) -> DbResult<()>;
252    async fn delete_group_user(&self, group_name: &str, user: &str) -> DbResult<()>;
253    async fn get_group_users(&self, group_name: &str) -> DbResult<Vec<User>>;
254    async fn is_group_user(&self, group_name: &str, group: &str) -> DbResult<bool>;
255    async fn add_crate_group(&self, crate_name: &NormalizedName, group: &str) -> DbResult<()>;
256    async fn delete_crate_group(&self, crate_name: &NormalizedName, group: &str) -> DbResult<()>;
257    async fn get_crate_groups(&self, crate_name: &NormalizedName) -> DbResult<Vec<Group>>;
258    async fn is_crate_group(&self, crate_name: &NormalizedName, group: &str) -> DbResult<bool>;
259    async fn is_crate_group_user(&self, crate_name: &NormalizedName, user: &str) -> DbResult<bool>;
260    async fn get_total_unique_crates(&self) -> DbResult<u64>;
261    async fn get_total_crate_versions(&self) -> DbResult<u64>;
262    async fn get_total_downloads(&self) -> DbResult<u64>;
263    async fn get_top_crates_downloads(
264        &self,
265        top: u64,
266        visibility: &CrateVisibility,
267    ) -> DbResult<Vec<(String, u64)>>;
268    async fn get_total_unique_cached_crates(&self) -> DbResult<u64>;
269    async fn get_total_cached_crate_versions(&self) -> DbResult<u64>;
270    async fn get_total_cached_downloads(&self) -> DbResult<u64>;
271    async fn get_crate_summaries(&self) -> DbResult<Vec<CrateSummary>>;
272    async fn add_doc_queue(
273        &self,
274        krate: &NormalizedName,
275        version: &Version,
276        path: &Path,
277    ) -> DbResult<()>;
278    async fn delete_doc_queue(&self, id: i64) -> DbResult<()>;
279    async fn get_doc_queue(&self) -> DbResult<Vec<DocQueueEntry>>;
280    async fn delete_crate(&self, krate: &NormalizedName, version: &Version) -> DbResult<()>;
281    async fn get_crate_meta_list(&self, crate_name: &NormalizedName) -> DbResult<Vec<CrateMeta>>;
282    async fn update_last_updated(&self, id: i64, last_updated: &DateTime<Utc>) -> DbResult<()>;
283    async fn search_in_crate_name_and_description(
284        &self,
285        contains: &str,
286        limit: u64,
287        offset: u64,
288        cache: bool,
289        visibility: &CrateVisibility,
290    ) -> DbResult<Vec<CrateOverview>>;
291    async fn count_by_crate_name_and_description(
292        &self,
293        contains: &str,
294        cache: bool,
295        visibility: &CrateVisibility,
296    ) -> DbResult<u64>;
297    async fn get_crate_overview_list(
298        &self,
299        limit: u64,
300        offset: u64,
301        cache: bool,
302        visibility: &CrateVisibility,
303        sort: CrateSort,
304        tags: &CrateTagFilter,
305    ) -> DbResult<Vec<CrateOverview>>;
306    async fn count_crate_overview_list(
307        &self,
308        cache: bool,
309        visibility: &CrateVisibility,
310        tags: &CrateTagFilter,
311    ) -> DbResult<u64>;
312    async fn get_crate_data(&self, crate_name: &NormalizedName) -> DbResult<CrateData>;
313    async fn add_empty_crate(&self, name: &str, created: &DateTime<Utc>) -> DbResult<i64>;
314    /// Adds a published crate version. `owner` is the publishing user, who
315    /// becomes the owner of a new crate. `token_name` is the name of the auth
316    /// token used to publish, `None` if unknown.
317    async fn add_crate(
318        &self,
319        pub_metadata: &PublishMetadata,
320        cksum: &str,
321        size: i64,
322        created: &DateTime<Utc>,
323        owner: &str,
324        token_name: Option<String>,
325    ) -> DbResult<i64>;
326    async fn update_docs_link(
327        &self,
328        crate_name: &NormalizedName,
329        version: &Version,
330        docs_link: &str,
331    ) -> DbResult<()>;
332    async fn add_crate_metadata(
333        &self,
334        pub_metadata: &PublishMetadata,
335        size: i64,
336        created: &str,
337        crate_id: i64,
338    ) -> DbResult<()>;
339    async fn get_prefetch_data(&self, crate_name: &str) -> DbResult<Prefetch>;
340    async fn is_cratesio_cache_up_to_date(
341        &self,
342        crate_name: &NormalizedName,
343        if_none_match: Option<String>,
344        if_modified_since: Option<String>,
345    ) -> DbResult<PrefetchState>;
346    async fn add_cratesio_prefetch_data(
347        &self,
348        crate_name: &OriginalName,
349        etag: &str,
350        last_modified: &str,
351        description: Option<String>,
352        indices: &[IndexMetadata],
353    ) -> DbResult<Prefetch>;
354    async fn get_cratesio_index_update_list(&self) -> DbResult<Vec<CratesioPrefetchMsg>>;
355    /// Checksum of a crates.io crate version from the cached index, if known.
356    async fn get_cratesio_cksum(
357        &self,
358        crate_name: &NormalizedName,
359        version: &Version,
360    ) -> DbResult<Option<String>>;
361    async fn unyank_crate(&self, crate_name: &NormalizedName, version: &Version) -> DbResult<()>;
362    async fn yank_crate(&self, crate_name: &NormalizedName, version: &Version) -> DbResult<()>;
363    async fn register_webhook(&self, webhook: Webhook) -> DbResult<String>;
364    async fn delete_webhook(&self, id: &str) -> DbResult<()>;
365    async fn get_webhook(&self, id: &str) -> DbResult<Webhook>;
366    async fn get_all_webhooks(&self) -> DbResult<Vec<Webhook>>;
367    /// Creates a new webhook queue entry for each register webhook
368    /// matching the given event. `Next_attempt` is set to current time,
369    ///  in order to trigger immediate dispatch.
370    async fn add_webhook_queue(
371        &self,
372        event: WebhookEvent,
373        payload: serde_json::Value,
374    ) -> DbResult<()>;
375    /// Extracts webhook queue entries with `next_attempt` at or earlier than provided timestamp.
376    async fn get_pending_webhook_queue_entries(
377        &self,
378        timestamp: DateTime<Utc>,
379    ) -> DbResult<Vec<WebhookQueue>>;
380    async fn update_webhook_queue(
381        &self,
382        id: &str,
383        last_attempt: DateTime<Utc>,
384        next_attempt: DateTime<Utc>,
385    ) -> DbResult<()>;
386    async fn delete_webhook_queue(&self, id: &str) -> DbResult<()>;
387
388    // `OAuth2` identity methods
389    /// Look up a user by their `OAuth2` identity (issuer + subject)
390    async fn get_user_by_oauth2_identity(
391        &self,
392        issuer: &str,
393        subject: &str,
394    ) -> DbResult<Option<User>>;
395
396    /// Whether any admin user has an `OAuth2` identity linked.
397    ///
398    /// Used at startup to tell a usable SSO-only deployment apart from one that
399    /// has locked itself out: the default local admin always exists, so the
400    /// presence of an admin alone says nothing.
401    async fn has_oauth2_admin(&self) -> DbResult<bool>;
402
403    /// Create a new user from `OAuth2` authentication and link their identity
404    async fn create_oauth2_user(
405        &self,
406        username: &str,
407        issuer: &str,
408        subject: &str,
409        email: Option<String>,
410        is_admin: bool,
411        is_read_only: bool,
412    ) -> DbResult<User>;
413
414    /// Link an `OAuth2` identity to an existing user
415    async fn link_oauth2_identity(
416        &self,
417        user_id: i64,
418        issuer: &str,
419        subject: &str,
420        email: Option<String>,
421    ) -> DbResult<()>;
422
423    // `OAuth2` state methods (CSRF/PKCE during auth flow)
424    /// Store `OAuth2` state for CSRF/PKCE verification during auth flow
425    async fn store_oauth2_state(
426        &self,
427        state: &str,
428        pkce_verifier: &str,
429        nonce: &str,
430    ) -> DbResult<()>;
431
432    /// Retrieve and delete `OAuth2` state (single use)
433    async fn get_and_delete_oauth2_state(&self, state: &str) -> DbResult<Option<OAuth2StateData>>;
434
435    /// Clean up expired `OAuth2` states (older than 10 minutes)
436    async fn cleanup_expired_oauth2_states(&self) -> DbResult<u64>;
437
438    /// Check if username is available (for `OAuth2` auto-provisioning)
439    async fn is_username_available(&self, username: &str) -> DbResult<bool>;
440
441    // Toolchain distribution methods
442    /// Add a new toolchain release
443    async fn add_toolchain(
444        &self,
445        name: &str,
446        version: &str,
447        date: &str,
448        channel: Option<String>,
449    ) -> DbResult<i64>;
450
451    /// Add a target archive to an existing toolchain
452    async fn add_toolchain_target(
453        &self,
454        toolchain_id: i64,
455        target: &str,
456        storage_path: &str,
457        hash: &str,
458        size: i64,
459    ) -> DbResult<i64>;
460
461    /// Add a component to a toolchain target
462    async fn add_toolchain_component(
463        &self,
464        target_id: i64,
465        name: &str,
466        storage_path: &str,
467        hash: &str,
468        size: i64,
469    ) -> DbResult<()>;
470
471    /// Update the processing status of a toolchain target
472    async fn set_target_status(&self, target_id: i64, status: &str) -> DbResult<()>;
473
474    /// Get a toolchain by its channel (e.g., "stable", "nightly")
475    async fn get_toolchain_by_channel(
476        &self,
477        channel: &str,
478    ) -> DbResult<Option<ToolchainWithTargets>>;
479
480    /// Get a toolchain by name and version
481    async fn get_toolchain_by_version(
482        &self,
483        name: &str,
484        version: &str,
485    ) -> DbResult<Option<ToolchainWithTargets>>;
486
487    /// List all toolchains
488    async fn list_toolchains(&self) -> DbResult<Vec<ToolchainWithTargets>>;
489
490    /// Delete a toolchain and all its targets
491    async fn delete_toolchain(&self, name: &str, version: &str) -> DbResult<()>;
492
493    /// Delete a specific toolchain target
494    async fn delete_toolchain_target(
495        &self,
496        name: &str,
497        version: &str,
498        target: &str,
499    ) -> DbResult<()>;
500
501    /// Set a channel to point to a specific toolchain version
502    async fn set_channel(&self, channel: &str, name: &str, version: &str) -> DbResult<()>;
503
504    /// Get all channels with their current versions
505    async fn get_channels(&self) -> DbResult<Vec<ChannelInfo>>;
506}
507
508pub mod mock {
509    use chrono::DateTime;
510    use mockall::predicate::*;
511    use mockall::*;
512
513    use super::*;
514
515    mock! {
516          pub Db {}
517
518        #[async_trait]
519        impl DbProvider for Db {
520
521            async fn get_last_updated_crate(&self, visibility: &CrateVisibility) -> DbResult<Option<(OriginalName, Version)>> {
522                unimplemented!()
523            }
524
525            async fn authenticate_user(&self, _name: &str, _pwd: &str) -> DbResult<User> {
526                unimplemented!()
527            }
528
529            async fn increase_download_counter(
530                &self,
531                _crate_name: &NormalizedName,
532                _crate_version: &Version,
533            ) -> DbResult<()> {
534                unimplemented!()
535            }
536
537            async fn increase_cached_download_counter(
538                &self,
539                _crate_name: &NormalizedName,
540                _crate_version: &Version,
541            ) -> DbResult<()> {
542                unimplemented!()
543            }
544
545            async fn increase_download_counter_by(
546                &self,
547                _crate_name: &NormalizedName,
548                _crate_version: &Version,
549                _count: u64,
550            ) -> DbResult<()> {
551                unimplemented!()
552            }
553
554            async fn increase_cached_download_counter_by(
555                &self,
556                _crate_name: &NormalizedName,
557                _crate_version: &Version,
558                _count: u64,
559            ) -> DbResult<()> {
560                unimplemented!()
561            }
562
563            async fn validate_session(&self, _session_token: &str) -> DbResult<SessionInfo> {
564                unimplemented!()
565            }
566
567            async fn delete_expired_sessions(&self) -> DbResult<u64> {
568                unimplemented!()
569            }
570
571            async fn add_session_token(&self, _name: &str, _session_token: &str) -> DbResult<()> {
572                unimplemented!()
573            }
574
575            async fn delete_user_sessions(&self, _user_name: &str) -> DbResult<u64> {
576                unimplemented!()
577            }
578
579            async fn delete_other_user_sessions(&self, _user_name: &str, _keep_session_token: &str) -> DbResult<u64> {
580                unimplemented!()
581            }
582
583            async fn add_crate_user(&self, crate_name: &NormalizedName, user: &str) -> DbResult<()> {
584                unimplemented!()
585            }
586
587            async fn add_owner(&self, _crate_name: &NormalizedName, _owner: &str) -> DbResult<()> {
588                unimplemented!()
589            }
590
591            async fn is_download_restricted(&self, crate_name: &NormalizedName) -> DbResult<bool> {
592                unimplemented!()
593            }
594
595            async fn change_download_restricted(
596                &self,
597                crate_name: &NormalizedName,
598                restricted: bool,
599            ) -> DbResult<()> {
600                unimplemented!()
601            }
602
603            async fn is_crate_user(&self, _crate_name: &NormalizedName, _user: &str) -> DbResult<bool> {
604                unimplemented!()
605            }
606
607            async fn is_owner(&self, _crate_name: &NormalizedName, _user: &str) -> DbResult<bool> {
608                unimplemented!()
609            }
610
611            async fn get_crate_id(&self, _crate_name: &NormalizedName) -> DbResult<Option<i64>> {
612                unimplemented!()
613            }
614
615            async fn get_crate_owners(&self, _crate_name: &NormalizedName) -> DbResult<Vec<User>> {
616                unimplemented!()
617            }
618
619            async fn get_crate_users(&self, _crate_name: &NormalizedName) -> DbResult<Vec<User>> {
620                unimplemented!()
621            }
622
623            async fn get_crate_versions(&self, _crate_name: &NormalizedName) -> DbResult<Vec<Version>> {
624                unimplemented!()
625            }
626
627            async fn delete_session_token(&self, _session_token: &str) -> DbResult<()> {
628                unimplemented!()
629            }
630
631            async fn delete_user(&self, _user_name: &str) -> DbResult<()> {
632                unimplemented!()
633            }
634
635            async fn change_pwd(&self, _user_name: &str, _new_pwd: &str) -> DbResult<()> {
636                unimplemented!()
637            }
638
639            async fn change_read_only_state(&self, _user_name: &str, _state: bool) -> DbResult<()> {
640                unimplemented!()
641            }
642
643            async fn change_admin_state(&self, _user_name: &str, _state: bool) -> DbResult<()> {
644                unimplemented!()
645            }
646
647            async fn crate_version_exists(&self, _crate_id: i64, _version: &str) -> DbResult<bool> {
648                unimplemented!()
649            }
650
651            async fn get_max_version_from_id(&self, crate_id: i64) -> DbResult<Version>  {
652                unimplemented!()
653            }
654
655            async fn get_max_version_from_name(&self, crate_name: &NormalizedName) -> DbResult<Version> {
656                unimplemented!()
657            }
658
659            async fn update_max_version(&self, crate_id: i64, version: &Version) -> DbResult<()> {
660                unimplemented!()
661            }
662
663            async fn add_auth_token(&self, _name: &str, _token: &str, _user: &str) -> DbResult<()> {
664                unimplemented!()
665            }
666
667            async fn get_auth_token_name(&self, token: &str) -> DbResult<Option<String>> {
668                unimplemented!()
669            }
670
671            async fn get_user_from_token(&self, _token: &str) -> DbResult<User> {
672                unimplemented!()
673            }
674
675            async fn get_user(&self, _name: &str) -> DbResult<User> {
676                unimplemented!()
677            }
678
679            async fn get_auth_tokens(&self, _user_name: &str) -> DbResult<Vec<AuthToken>> {
680                unimplemented!()
681            }
682
683            async fn delete_auth_token(&self, _id: i32) -> DbResult<()> {
684                unimplemented!()
685            }
686
687            async fn delete_owner(&self, _crate_name: &str, _owner: &str) -> DbResult<()> {
688                unimplemented!()
689            }
690
691            async fn delete_crate_user(&self, crate_name: &NormalizedName, user: &str) -> DbResult<()>{
692                unimplemented!()
693            }
694
695            async fn add_user(&self, _name: &str, _pwd: &str, _is_admin: bool, _is_read_only: bool) -> DbResult<()> {
696                unimplemented!()
697            }
698
699            async fn get_users(&self) -> DbResult<Vec<User>> {
700                unimplemented!()
701            }
702
703            async fn get_total_unique_crates(&self) -> DbResult<u64> {
704                unimplemented!()
705            }
706
707            async fn get_total_crate_versions(&self) -> DbResult<u64> {
708                unimplemented!()
709            }
710
711            async fn get_top_crates_downloads(&self, _top: u64, visibility: &CrateVisibility) -> DbResult<Vec<(String, u64)>> {
712                unimplemented!()
713            }
714
715            async fn get_total_unique_cached_crates(&self) -> DbResult<u64> {
716                unimplemented!()
717            }
718
719            async fn get_total_cached_crate_versions(&self) -> DbResult<u64> {
720                unimplemented!()
721            }
722
723            async fn get_total_cached_downloads(&self) -> DbResult<u64> {
724                unimplemented!()
725            }
726
727            async fn get_crate_summaries(&self) -> DbResult<Vec<CrateSummary >> {
728                unimplemented!()
729            }
730
731                async fn add_doc_queue(&self, krate: &NormalizedName, version: &Version, path: &Path) -> DbResult<()>{
732                    unimplemented!()
733                }
734
735            async fn delete_doc_queue(&self, id: i64) -> DbResult<()>{
736                    unimplemented!()
737                }
738
739            async fn get_doc_queue(&self) -> DbResult<Vec<DocQueueEntry>> {
740                unimplemented!()
741            }
742
743            async fn delete_crate(&self, krate: &NormalizedName, version: &Version) -> DbResult<()> {
744                unimplemented!()
745            }
746
747            async fn get_total_downloads(&self) -> DbResult<u64>{
748                unimplemented!()
749            }
750
751            async fn get_crate_meta_list(&self, crate_name: &NormalizedName) -> DbResult<Vec<CrateMeta>>{
752                unimplemented!()
753            }
754
755            async fn update_last_updated(&self, id: i64, last_updated: &DateTime<Utc>) -> DbResult<()>{
756                unimplemented!()
757            }
758
759            async fn search_in_crate_name_and_description(&self, contains: &str, limit: u64, offset: u64, cache: bool, visibility: &CrateVisibility) -> DbResult<Vec<CrateOverview>> {
760                unimplemented!()
761            }
762
763            async fn count_by_crate_name_and_description(&self, contains: &str, cache: bool, visibility: &CrateVisibility) -> DbResult<u64> {
764                unimplemented!()
765            }
766
767            async fn get_crate_overview_list(&self, limit: u64, offset: u64, cache: bool, visibility: &CrateVisibility, sort: CrateSort, tags: &CrateTagFilter) -> DbResult<Vec<CrateOverview >> {
768                unimplemented!()
769            }
770
771            async fn count_crate_overview_list(&self, cache: bool, visibility: &CrateVisibility, tags: &CrateTagFilter) -> DbResult<u64> {
772                unimplemented!()
773            }
774
775            async fn get_crate_data(&self, crate_name: &NormalizedName) -> DbResult<CrateData> {
776                unimplemented!()
777            }
778
779            async fn add_empty_crate(&self, name: &str, created: &DateTime<Utc>) -> DbResult<i64> {
780                unimplemented!()
781            }
782
783            async fn add_crate(&self, pub_metadata: &PublishMetadata, sha256: &str, size: i64, created: &DateTime<Utc>, owner: &str, token_name: Option<String>) -> DbResult<i64> {
784                unimplemented!()
785            }
786
787            async fn update_docs_link(&self, crate_name: &NormalizedName, version: &Version, docs_link: &str) -> DbResult<()> {
788                unimplemented!()
789            }
790
791            async fn add_crate_metadata(&self, pub_metadata: &PublishMetadata, size: i64, created: &str, crate_id: i64,) -> DbResult<()> {
792                unimplemented!()
793            }
794
795            async fn get_prefetch_data(&self, crate_name: &str) -> DbResult<Prefetch> {
796                unimplemented!()
797            }
798
799            async fn is_cratesio_cache_up_to_date(&self, crate_name: &NormalizedName, etag: Option<String>, last_modified: Option<String>) -> DbResult<PrefetchState> {
800                unimplemented!()
801            }
802
803            async fn add_cratesio_prefetch_data(
804                &self,
805                crate_name: &OriginalName,
806                etag: &str,
807                last_modified: &str,
808                description: Option<String>,
809                indices: &[IndexMetadata],
810            ) -> DbResult<Prefetch> {
811                unimplemented!()
812            }
813
814            async fn get_cratesio_index_update_list(&self) -> DbResult<Vec<CratesioPrefetchMsg>> {
815                unimplemented!()
816            }
817
818            async fn get_cratesio_cksum(&self, crate_name: &NormalizedName, version: &Version) -> DbResult<Option<String>> {
819                unimplemented!()
820            }
821
822            async fn unyank_crate(&self, crate_name: &NormalizedName, version: &Version) -> DbResult<()> {
823                unimplemented!()
824            }
825
826            async fn yank_crate(&self, crate_name: &NormalizedName, version: &Version) -> DbResult<()> {
827                unimplemented!()
828            }
829
830            async fn add_group(&self, name: &str) -> DbResult<()> {
831                        unimplemented!()
832            }
833            async fn get_group(&self, name: &str) -> DbResult<Group>{
834                        unimplemented!()
835            }
836            async fn get_groups(&self) -> DbResult<Vec<Group>>{
837                        unimplemented!()
838            }
839            async fn delete_group(&self, name: &str) -> DbResult<()>{
840                        unimplemented!()
841            }
842            async fn add_group_user(&self, group_name: &str, user: &str) -> DbResult<()>{
843                        unimplemented!()
844            }
845            async fn delete_group_user(&self, group_name: &str, user: &str) -> DbResult<()>{
846                        unimplemented!()
847            }
848            async fn get_group_users(&self, group_name: &str) -> DbResult<Vec<User>> {
849                unimplemented!()
850            }
851            async fn is_group_user(&self, group_name: &str, user: &str) -> DbResult<bool> {
852                unimplemented!()
853            }
854
855            async fn add_crate_group(&self, crate_name: &NormalizedName, group: &str) -> DbResult<()>{
856                unimplemented!()
857            }
858            async fn delete_crate_group(&self, crate_name: &NormalizedName, group: &str) -> DbResult<()>{
859                unimplemented!()
860            }
861            async fn get_crate_groups(&self, crate_name: &NormalizedName) -> DbResult<Vec<Group>>{
862                unimplemented!()
863            }
864            async fn is_crate_group(&self, crate_name: &NormalizedName, group: &str) -> DbResult<bool>{
865                unimplemented!()
866            }
867
868            async fn is_crate_group_user(&self, crate_name: &NormalizedName, user: &str) -> DbResult<bool>{
869                unimplemented!()
870            }
871
872            async fn register_webhook(
873                &self,
874                webhook: Webhook
875            ) -> DbResult<String> {
876                unimplemented!()
877            }
878            async fn delete_webhook(&self, id: &str) -> DbResult<()> {
879                unimplemented!()
880            }
881            async fn get_webhook(&self, id: &str) -> DbResult<Webhook> {
882                unimplemented!()
883            }
884            async fn get_all_webhooks(&self) -> DbResult<Vec<Webhook>> {
885                unimplemented!()
886            }
887            async fn add_webhook_queue(&self, event: WebhookEvent, payload: serde_json::Value) -> DbResult<()> {
888                unimplemented!()
889            }
890            async fn get_pending_webhook_queue_entries(&self, timestamp: DateTime<Utc>) -> DbResult<Vec<WebhookQueue>> {
891                unimplemented!()
892            }
893            async fn update_webhook_queue(&self, id: &str, last_attempt: DateTime<Utc>, next_attempt: DateTime<Utc>) -> DbResult<()> {
894                unimplemented!()
895            }
896            async fn delete_webhook_queue(&self, id: &str) -> DbResult<()> {
897                unimplemented!()
898            }
899
900            async fn get_user_by_oauth2_identity(
901                &self,
902                issuer: &str,
903                subject: &str,
904            ) -> DbResult<Option<User>> {
905                unimplemented!()
906            }
907
908            async fn has_oauth2_admin(&self) -> DbResult<bool> {
909                unimplemented!()
910            }
911
912            async fn create_oauth2_user(
913                &self,
914                username: &str,
915                issuer: &str,
916                subject: &str,
917                email: Option<String>,
918                is_admin: bool,
919                is_read_only: bool,
920            ) -> DbResult<User> {
921                unimplemented!()
922            }
923
924            async fn link_oauth2_identity(
925                &self,
926                user_id: i64,
927                issuer: &str,
928                subject: &str,
929                email: Option<String>,
930            ) -> DbResult<()> {
931                unimplemented!()
932            }
933
934            async fn store_oauth2_state(
935                &self,
936                state: &str,
937                pkce_verifier: &str,
938                nonce: &str,
939            ) -> DbResult<()> {
940                unimplemented!()
941            }
942
943            async fn get_and_delete_oauth2_state(
944                &self,
945                state: &str,
946            ) -> DbResult<Option<OAuth2StateData>> {
947                unimplemented!()
948            }
949
950            async fn cleanup_expired_oauth2_states(&self) -> DbResult<u64> {
951                unimplemented!()
952            }
953
954            async fn is_username_available(&self, username: &str) -> DbResult<bool> {
955                unimplemented!()
956            }
957
958            async fn add_toolchain(
959                &self,
960                name: &str,
961                version: &str,
962                date: &str,
963                channel: Option<String>,
964            ) -> DbResult<i64> {
965                unimplemented!()
966            }
967
968            async fn add_toolchain_target(
969                &self,
970                toolchain_id: i64,
971                target: &str,
972                storage_path: &str,
973                hash: &str,
974                size: i64,
975            ) -> DbResult<i64> {
976                unimplemented!()
977            }
978
979            async fn add_toolchain_component(
980                &self,
981                target_id: i64,
982                name: &str,
983                storage_path: &str,
984                hash: &str,
985                size: i64,
986            ) -> DbResult<()> {
987                unimplemented!()
988            }
989
990            async fn set_target_status(&self, target_id: i64, status: &str) -> DbResult<()> {
991                unimplemented!()
992            }
993
994            async fn get_toolchain_by_channel(&self, channel: &str) -> DbResult<Option<ToolchainWithTargets>> {
995                unimplemented!()
996            }
997
998            async fn get_toolchain_by_version(
999                &self,
1000                name: &str,
1001                version: &str,
1002            ) -> DbResult<Option<ToolchainWithTargets>> {
1003                unimplemented!()
1004            }
1005
1006            async fn list_toolchains(&self) -> DbResult<Vec<ToolchainWithTargets>> {
1007                unimplemented!()
1008            }
1009
1010            async fn delete_toolchain(&self, name: &str, version: &str) -> DbResult<()> {
1011                unimplemented!()
1012            }
1013
1014            async fn delete_toolchain_target(
1015                &self,
1016                name: &str,
1017                version: &str,
1018                target: &str,
1019            ) -> DbResult<()> {
1020                unimplemented!()
1021            }
1022
1023            async fn set_channel(&self, channel: &str, name: &str, version: &str) -> DbResult<()> {
1024                unimplemented!()
1025            }
1026
1027            async fn get_channels(&self) -> DbResult<Vec<ChannelInfo>> {
1028                unimplemented!()
1029            }
1030        }
1031    }
1032}