Skip to main content

kellnr_db/
provider.rs

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