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
108
109
110
111
112
113
114
//! rustlavel-oauth-provider: be an OAuth 2.1 authorization server.
//!
//! This is Laravel Passport's job — letting *other* applications sign users in
//! through yours. The mirror half, signing your users in through somebody
//! else's, is `rustlavel-oauth`, whose types this crate speaks so both ends
//! agree on the wire format by construction.
//!
//! ```ignore
//! use rustlavel_oauth_provider::prelude::*;
//!
//! let clients = MemoryClientStore::new().with(
//! Client::confidential("checkout", &secret)
//! .named("Checkout")
//! .redirect_uri("https://checkout.test/oauth/callback")
//! .scopes(Scopes::of(["orders.read", "orders.write"])),
//! );
//!
//! App::new()?
//! .plugin(OAuthProvider::new(
//! AuthorizationServer::new(clients).issued_by("https://accounts.example.com"),
//! ))
//! .serve()
//! .await
//! ```
//!
//! That mounts six routes: `/oauth/authorize` (`GET` and `POST`),
//! `/oauth/token`, `/oauth/revoke`, `/oauth/introspect`, and the RFC 8414
//! discovery document at `/.well-known/oauth-authorization-server`. Guarding
//! your own API with the tokens it issues is [`RequireToken`].
//!
//! # What this server will not do
//!
//! It is OAuth **2.1**, not 2.0 with the dangerous parts left in:
//!
//! * **PKCE is required**, for every client, and only `S256` is accepted.
//! `plain` is refused, and an absent `code_challenge_method` is an error
//! rather than a default — RFC 7636 §4.3 defaults it to `plain`, which would
//! let a client turn PKCE off by omitting a parameter.
//! * **The implicit flow is gone.** `response_type=token` returns an access
//! token in a URL fragment, where it lands in browser history and in every
//! script on the page.
//! * **The password grant is gone.** It asks the user to type their password
//! into somebody else's application, cannot carry a second factor, and hands
//! the client a credential that works everywhere.
//! * **Redirect URIs are matched byte for byte** against the registered set. No
//! prefixes, no wildcards. [`redirect`] explains what each relaxation lets
//! through.
//! * **A leaked credential takes its family down with it.** A replayed
//! authorisation code and a reused refresh token both revoke every token
//! descended from that authorisation, because either one means two parties
//! hold a credential that was issued to one.
//!
//! # Where the data lives
//!
//! Four traits — [`ClientStore`], [`CodeStore`], [`TokenStore`],
//! [`ConsentStore`] — each with two implementations: an in-memory one for tests
//! and a development server, and a table-backed one in `database` behind the
//! `db` feature. **Deploy the second.** A restart empties the first, and an
//! empty store answers "unknown token" to everything.
//!
//! The database is optional rather than absent: an application with no database
//! compiles none of it, and one with its own tables implements the traits
//! instead. See [`store`] for the reasoning, and for the two operations that
//! must be atomic whichever you use.
//!
//! # Cryptography
//!
//! SHA-256, from `sha2`, is the only primitive here: every credential is stored
//! as a digest and compared in constant time, and PKCE's `S256` is the same
//! hash. Nothing else is invented. There is no JWT option and no JWKS: an
//! access token here is opaque so that revoking it revokes it, which a
//! self-contained signed token cannot offer.
/// The stores, backed by a table each. Behind the `db` feature: an
/// authorization server with its own storage should not drag the database
/// package into one that has none.
pub use ;
pub use Clock;
pub use ;
pub use ;
pub use OAuthProvider;
pub use ;
pub use ;
pub use StoreFuture;
pub use ;
/// The protocol vocabulary, re-exported so an application needs one import.
pub use ;
pub use ;
/// What a `main.rs` or a controller imports to use this package.