1#![cfg_attr(docsrs, feature(doc_cfg))]
2
3use async_trait::async_trait;
4use http::header::AUTHORIZATION;
5use http::{HeaderMap, StatusCode};
6
7#[cfg(feature = "yes-backend")]
8#[cfg_attr(docsrs, doc(cfg(feature = "yes-backend")))]
9pub mod yes_backend;
10
11pub mod no_backend;
12
13#[cfg(feature = "pg-backend")]
14#[cfg_attr(docsrs, doc(cfg(feature = "pg-backend")))]
15pub mod pg_backend;
16
17#[cfg(feature = "fs-backend")]
18#[cfg_attr(docsrs, doc(cfg(feature = "fs-backend")))]
19pub mod fs_backend;
20
21#[cfg(feature = "fs-backend")]
22mod base64_serde;
23
24mod error;
25
26#[cfg(feature = "cf-backend")]
27mod cf_access;
28
29#[cfg(feature = "cf-backend")]
30#[cfg_attr(docsrs, doc(cfg(feature = "cf-backend")))]
31pub mod cf_backend;
32
33pub use error::*;
34use freighter_api_types::ownership::response::ListedOwner;
35
36#[async_trait]
37pub trait AuthProvider {
38 type Config;
39
40 async fn healthcheck(&self) -> anyhow::Result<()>;
41
42 async fn register(&self, username: &str) -> AuthResult<String>;
44
45 async fn list_owners(&self, token: &str, crate_name: &str) -> AuthResult<Vec<ListedOwner>>;
47 async fn add_owners(&self, token: &str, users: &[&str], crate_name: &str) -> AuthResult<()>;
49 async fn remove_owners(&self, token: &str, users: &[&str], crate_name: &str) -> AuthResult<()>;
51
52 async fn publish(&self, token: &str, crate_name: &str) -> AuthResult<()>;
57
58 async fn auth_yank(&self, token: &str, crate_name: &str) -> AuthResult<()>;
60
61 async fn auth_index_fetch(&self, token: &str, crate_name: &str) -> AuthResult<()> {
66 let _ = (token, crate_name);
67 Err(AuthError::Unimplemented)
68 }
69
70 async fn auth_crate_download(&self, token: &str, crate_name: &str) -> AuthResult<()> {
75 let _ = (token, crate_name);
76 Err(AuthError::Unimplemented)
77 }
78
79 async fn auth_view_full_index(&self, token: &str) -> AuthResult<()> {
86 let _ = token;
87 Err(AuthError::Unimplemented)
88 }
89
90 async fn auth_config(&self, token: &str) -> AuthResult<()> {
92 let _ = token;
93 Err(AuthError::Unimplemented)
94 }
95
96 fn token_from_headers<'h>(&self, headers: &'h HeaderMap) -> Result<Option<&'h str>, StatusCode> {
97 default_token_from_headers(headers)
98 }
99}
100
101pub(crate) fn default_token_from_headers(headers: &HeaderMap) -> Result<Option<&str>, StatusCode> {
102 match headers.get(AUTHORIZATION) {
103 Some(auth) => auth.to_str().map_err(|_| StatusCode::BAD_REQUEST).map(Some),
104 None => Ok(None),
105 }
106}