1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
use std::collections::HashMap;
use kittybox_indieauth::{
AuthorizationRequest, TokenData
};
pub use kittybox_util::auth::EnrolledCredential;
type Result<T> = std::io::Result<T>;
pub mod fs;
pub use fs::FileBackend;
#[async_trait::async_trait]
pub trait AuthBackend: Clone + Send + Sync + 'static {
/// Initialize self from URL, possibly performing initialization.
async fn new(url: &'_ url::Url) -> Result<Self>;
// Authorization code management.
/// Create a one-time OAuth2 authorization code for the passed
/// authorization request, and save it for later retrieval.
///
/// Note for implementors: the [`AuthorizationRequest::me`] value
/// is guaranteed to be [`Some(url::Url)`][Option::Some] and can
/// be trusted to be correct and non-malicious.
async fn create_code(&self, data: AuthorizationRequest) -> Result<String>;
/// Retreive an authorization request using the one-time
/// code. Implementations must sanitize the `code` field to
/// prevent exploits, and must check if the code should still be
/// valid at this point in time (validity interval is left up to
/// the implementation, but is recommended to be no more than 10
/// minutes).
async fn get_code(&self, code: &str) -> Result<Option<AuthorizationRequest>>;
// Token management.
async fn create_token(&self, data: TokenData) -> Result<String>;
async fn get_token(&self, website: &url::Url, token: &str) -> Result<Option<TokenData>>;
async fn list_tokens(&self, website: &url::Url) -> Result<HashMap<String, TokenData>>;
async fn revoke_token(&self, website: &url::Url, token: &str) -> Result<()>;
// Refresh token management.
async fn create_refresh_token(&self, data: TokenData) -> Result<String>;
async fn get_refresh_token(&self, website: &url::Url, token: &str) -> Result<Option<TokenData>>;
async fn list_refresh_tokens(&self, website: &url::Url) -> Result<HashMap<String, TokenData>>;
async fn revoke_refresh_token(&self, website: &url::Url, token: &str) -> Result<()>;
// Password management.
/// Verify a password.
#[must_use]
async fn verify_password(&self, website: &url::Url, password: String) -> Result<bool>;
/// Enroll a password credential for a user. Only one password
/// credential must exist for a given user.
async fn enroll_password(&self, website: &url::Url, password: String) -> Result<()>;
/// List currently enrolled credential types for a given user.
async fn list_user_credential_types(&self, website: &url::Url) -> Result<Vec<EnrolledCredential>>;
// WebAuthn credential management.
#[cfg(feature = "webauthn")]
/// Enroll a WebAuthn authenticator public key for this user.
/// Multiple public keys may be saved for one user, corresponding
/// to different authenticators used by them.
///
/// This function can also be used to overwrite a passkey with an
/// updated version after using
/// [webauthn::prelude::Passkey::update_credential()].
async fn enroll_webauthn(&self, website: &url::Url, credential: webauthn::prelude::Passkey) -> Result<()>;
#[cfg(feature = "webauthn")]
/// List currently enrolled WebAuthn authenticators for a given user.
async fn list_webauthn_pubkeys(&self, website: &url::Url) -> Result<Vec<webauthn::prelude::Passkey>>;
#[cfg(feature = "webauthn")]
/// Persist registration challenge state for a little while so it
/// can be used later.
///
/// Challenges saved in this manner MUST expire after a little
/// while. 10 minutes is recommended.
async fn persist_registration_challenge(
&self,
website: &url::Url,
state: webauthn::prelude::PasskeyRegistration
) -> Result<String>;
#[cfg(feature = "webauthn")]
/// Retrieve a persisted registration challenge.
///
/// The challenge should be deleted after retrieval.
async fn retrieve_registration_challenge(
&self,
website: &url::Url,
challenge_id: &str
) -> Result<webauthn::prelude::PasskeyRegistration>;
#[cfg(feature = "webauthn")]
/// Persist authentication challenge state for a little while so
/// it can be used later.
///
/// Challenges saved in this manner MUST expire after a little
/// while. 10 minutes is recommended.
///
/// To support multiple authentication options, this can return an
/// opaque token that should be set as a cookie.
async fn persist_authentication_challenge(
&self,
website: &url::Url,
state: webauthn::prelude::PasskeyAuthentication
) -> Result<String>;
#[cfg(feature = "webauthn")]
/// Retrieve a persisted authentication challenge.
///
/// The challenge should be deleted after retrieval.
async fn retrieve_authentication_challenge(
&self,
website: &url::Url,
challenge_id: &str
) -> Result<webauthn::prelude::PasskeyAuthentication>;
}
|