atproto_oauth_aip/
resources.rs

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