atproto_oauth_aip/
lib.rs

1//! OAuth AIP (Identity Provider) implementation for AT Protocol.
2//!
3//! Complete OAuth 2.0 authorization code flow with PAR, PKCE, token exchange,
4//! and AT Protocol session management for identity providers.
5//! ```rust,no_run
6//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
7//! use atproto_oauth_aip::workflow::{oauth_init, oauth_complete, session_exchange, OAuthClient};
8//! use atproto_oauth::resources::AuthorizationServer;
9//! use atproto_oauth::workflow::OAuthRequestState;
10//!
11//! let http_client = reqwest::Client::new();
12//! let oauth_client = OAuthClient {
13//!     redirect_uri: "https://redirect.example.com/callback".to_string(),
14//!     client_id: "client123".to_string(),
15//!     client_secret: "secret456".to_string(),
16//! };
17//!
18//! let authorization_server = AuthorizationServer {
19//!     issuer: "https://auth.example.com".to_string(),
20//!     authorization_endpoint: "https://auth.example.com/authorize".to_string(),
21//!     token_endpoint: "https://auth.example.com/token".to_string(),
22//!     pushed_authorization_request_endpoint: "https://auth.example.com/par".to_string(),
23//!     introspection_endpoint: "".to_string(),
24//!     scopes_supported: vec!["atproto".to_string(), "transition:generic".to_string()],
25//!     response_types_supported: vec!["code".to_string()],
26//!     grant_types_supported: vec!["authorization_code".to_string(), "refresh_token".to_string()],
27//!     token_endpoint_auth_methods_supported: vec!["none".to_string(), "private_key_jwt".to_string()],
28//!     token_endpoint_auth_signing_alg_values_supported: vec!["ES256".to_string()],
29//!     require_pushed_authorization_requests: true,
30//!     request_parameter_supported: false,
31//!     code_challenge_methods_supported: vec!["S256".to_string()],
32//!     authorization_response_iss_parameter_supported: true,
33//!     dpop_signing_alg_values_supported: vec!["ES256".to_string()],
34//!     client_id_metadata_document_supported: true,
35//! };
36//!
37//! let oauth_request_state = OAuthRequestState {
38//!     state: "random-state".to_string(),
39//!     nonce: "random-nonce".to_string(),
40//!     code_challenge: "code-challenge".to_string(),
41//!     scope: "atproto transition:generic".to_string(),
42//! };
43//!
44//! // Initialize OAuth flow with PAR
45//! let par_response = oauth_init(
46//!     &http_client,
47//!     &oauth_client,
48//!     Some("user_handle"),
49//!     &authorization_server.pushed_authorization_request_endpoint,
50//!     &oauth_request_state
51//! ).await?;
52//!
53//! // Complete OAuth flow with authorization code
54//! # let oauth_request = atproto_oauth::workflow::OAuthRequest {
55//! #     oauth_state: "state".to_string(),
56//! #     issuer: "https://auth.example.com".to_string(),
57//! #     authorization_server: "https://auth.example.com".to_string(),
58//! #     nonce: "nonce".to_string(),
59//! #     signing_public_key: "public_key".to_string(),
60//! #     pkce_verifier: "verifier".to_string(),
61//! #     dpop_private_key: "private_key".to_string(),
62//! #     created_at: chrono::Utc::now(),
63//! #     expires_at: chrono::Utc::now() + chrono::Duration::hours(1),
64//! # };
65//! let token_response = oauth_complete(
66//!     &http_client,
67//!     &oauth_client,
68//!     &authorization_server.token_endpoint,
69//!     "authorization_code",
70//!     &oauth_request
71//! ).await?;
72//!
73//! // Exchange tokens for AT Protocol session
74//! # let protected_resource = atproto_oauth::resources::OAuthProtectedResource {
75//! #     resource: "https://pds.example.com".to_string(),
76//! #     scopes_supported: vec!["atproto".to_string()],
77//! #     bearer_methods_supported: vec!["header".to_string()],
78//! #     authorization_servers: vec!["https://auth.example.com".to_string()],
79//! # };
80//! let session = session_exchange(
81//!     &http_client,
82//!     &protected_resource.resource,
83//!     &token_response.access_token
84//! ).await?;
85//! # Ok(())
86//! # }
87//! ```
88//!
89//! ## Error Handling
90//!
91//! All operations use structured error types with descriptive messages following
92//! the project's error convention format.
93
94#![forbid(unsafe_code)]
95#![warn(missing_docs)]
96
97/// Error types for OAuth workflow operations.
98pub mod errors;
99/// Resource definitions for OAuth operations.
100pub mod resources;
101/// OAuth workflow implementation.
102pub mod workflow;