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
//! axum 0.8 integration (the `axum08` feature): extractors and the
//! `/api/auth` JSON routes. A WebSocket watches its session with
//! [`Auth::guard`](crate::Auth::guard), which needs no axum.
//!
//! Every extractor and the routes need [`Auth`](crate::Auth) to be
//! extractable from the app's state, through `FromRef`. An app whose state
//! *is* the `Auth` gets that for free; otherwise derive or implement
//! `FromRef<AppState> for Auth`.
//!
//! ```no_run
//! # extern crate axum08 as axum;
//! use std::net::SocketAddr;
//!
//! use watchword::axum08::{SignedIn, routes};
//! use watchword::{Auth, MemoryStore, generate_session_key};
//! use axum::Router;
//! use axum::routing::get;
//!
//! # async fn run() -> std::io::Result<()> {
//! let auth = Auth::builder(MemoryStore::new(), generate_session_key()).build();
//!
//! let app = Router::new()
//! .route("/api/hello", get(|user: SignedIn| async move { format!("Hello {}", user.user.id) }))
//! .merge(routes())
//! .with_state(auth);
//!
//! let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await?;
//! // The sign-in route throttles by the client's address, so serve with
//! // connect info.
//! axum::serve(listener, app.into_make_service_with_connect_info::<SocketAddr>()).await
//! # }
//! ```
//!
//! Errors are answered as an [`AuthError`](crate::AuthError) JSON body with
//! its [status](crate::AuthError::status), and internal failures (such as
//! the store failing) as a 500 that is logged with `tracing`. Both
//! [`AuthError`](crate::AuthError) and [`core::Error`](crate::core::Error)
//! implement `IntoResponse`, so an app's own handlers can return them too.
//!
//! The design is in `docs/design.md`, section 2.6.
pub use ;
pub use LiveCache;
pub use routes;