atproto_oauth_aip/resources.rs
1//! OAuth resource discovery for AT Protocol identity providers.
2
3use atproto_oauth::{
4 errors::OAuthClientError,
5 resources::{AuthorizationServer, OAuthProtectedResource},
6};
7
8/// Fetch OAuth protected resource metadata from an AIP server.
9///
10/// # Arguments
11///
12/// * `http_client` - The HTTP client to use for making the request
13/// * `aip_server` - The base URL of the AIP server (e.g., "https://example.com")
14///
15/// # Returns
16///
17/// Returns the OAuth protected resource metadata on success, or an error if:
18/// - The HTTP request fails
19/// - The response cannot be parsed as valid OAuth protected resource metadata
20///
21/// # Example
22///
23/// ```no_run
24/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
25/// # let http_client = reqwest::Client::new();
26/// use atproto_oauth_aip::resources::oauth_protected_resource;
27/// let resource = oauth_protected_resource(&http_client, "https://bsky.social").await?;
28/// # Ok(())
29/// # }
30/// ```
31pub async fn oauth_protected_resource(
32 http_client: &reqwest::Client,
33 aip_server: &str,
34) -> Result<OAuthProtectedResource, OAuthClientError> {
35 let destination = format!("{}/.well-known/oauth-protected-resource", aip_server);
36
37 let resource: OAuthProtectedResource = http_client
38 .get(destination)
39 .send()
40 .await
41 .map_err(OAuthClientError::OAuthProtectedResourceRequestFailed)?
42 .json()
43 .await
44 .map_err(OAuthClientError::MalformedOAuthProtectedResourceResponse)?;
45
46 Ok(resource)
47}
48
49/// Fetches OAuth authorization server metadata from an AIP server.
50///
51/// This function retrieves the OAuth authorization server configuration from
52/// the well-known endpoint of an AT Protocol Identity Provider (AIP) server.
53/// The metadata includes essential information such as:
54/// - Authorization endpoint URL
55/// - Token endpoint URL
56/// - Pushed Authorization Request (PAR) endpoint URL
57/// - Supported OAuth flows and capabilities
58/// - JWKS (JSON Web Key Set) endpoint
59///
60/// # Arguments
61///
62/// * `http_client` - The HTTP client to use for making the request
63/// * `aip_server` - The base URL of the AIP server (e.g., "https://example.com")
64///
65/// # Returns
66///
67/// Returns the OAuth authorization server metadata on success, or an error if:
68/// - The HTTP request fails
69/// - The response cannot be parsed as valid OAuth authorization server metadata
70///
71/// # Example
72///
73/// ```no_run
74/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
75/// # let http_client = reqwest::Client::new();
76/// use atproto_oauth_aip::resources::oauth_authorization_server;
77/// let auth_server = oauth_authorization_server(&http_client, "https://bsky.social").await?;
78/// println!("Authorization endpoint: {}", auth_server.authorization_endpoint);
79/// println!("Token endpoint: {}", auth_server.token_endpoint);
80/// # Ok(())
81/// # }
82/// ```
83pub async fn oauth_authorization_server(
84 http_client: &reqwest::Client,
85 aip_server: &str,
86) -> Result<AuthorizationServer, OAuthClientError> {
87 let destination = format!("{}/.well-known/oauth-authorization-server", aip_server);
88
89 let resource: AuthorizationServer = http_client
90 .get(destination)
91 .send()
92 .await
93 .map_err(OAuthClientError::AuthorizationServerRequestFailed)?
94 .json()
95 .await
96 .map_err(OAuthClientError::MalformedAuthorizationServerResponse)?;
97
98 Ok(resource)
99}