cesium_oauth/auth/
account.rs

1use log::{debug, trace};
2use serde::{Deserialize, Serialize};
3
4use crate::error::Error;
5
6/// Information about a user, available after authentication.
7#[derive(Serialize, Deserialize, Clone, Debug)]
8pub struct Account {
9    /// The account id
10    pub id: String,
11    /// The username of the account, not including domain
12    pub username: String,
13    /// The profile’s display name
14    pub display_name: String,
15    /// An image icon that is shown next to statuses and in the profile
16    pub avatar: String,
17}
18
19/// Verify an obtained token and obtain information about the user.
20///
21/// # Errors
22///
23/// This method fails if there was an issue connecting to the instance, or
24/// if the `access_token` is invalid.
25///
26/// # Example
27///
28/// ```no_run
29/// # use cesium_oauth::apps::{AppInfo, AppProvider, FileCachedAppProvider, RegisteredApp};
30/// # use cesium_oauth::auth;
31/// # async fn get_app(app_info: &AppInfo) -> Result<RegisteredApp, cesium_oauth::Error> {
32/// # let mut provider = FileCachedAppProvider::new("apps.toml", app_info.clone())?;
33/// # provider.get_app_for("mastodon.art").await
34/// # }
35/// # async fn run() -> Result<(), cesium_oauth::Error> {
36/// # let app_info = AppInfo::new("Test App", "https://example.org");
37/// # let app = get_app(&app_info).await?;
38/// let token = auth::get_auth_token("mastodon.art", "[CODE]", &app, &app_info).await?;
39/// # Ok(())
40/// # }
41pub async fn verify_credentials(
42    instance_domain: &str,
43    access_token: &str,
44) -> Result<Account, Error> {
45    let url = format!("https://{instance_domain}/api/v1/accounts/verify_credentials");
46
47    debug!("Verifying account access at `{instance_domain}`");
48
49    let client = reqwest::Client::new();
50    let response = client
51        .get(&url)
52        .header("Authorization", &format!("Bearer {access_token}"))
53        .send()
54        .await
55        .map_err(|_| Error::TokenVerifyError("Failed to connect to server"))?;
56
57    trace!("Response status {}", response.status());
58    if response.status() != 200 {
59        return Err(Error::TokenVerifyError("Authorization failure"));
60    }
61
62    let account: Account = response
63        .json()
64        .await
65        .map_err(|_| Error::TokenVerifyError("Unable to parse response from server"))?;
66
67    debug!("Account details obtained for '{}'", account.username);
68
69    Ok(account)
70}