1use serde::Deserialize;
4
5use crate::error::ClientError;
6
7#[derive(Debug, Clone, Deserialize)]
8#[serde(rename_all = "camelCase")]
9pub struct Me {
10 pub id: String,
11 pub user_principal_name: String,
12 #[serde(default)]
13 pub display_name: Option<String>,
14 #[serde(default)]
15 pub mail: Option<String>,
16}
17
18pub async fn get_me(
19 http: &reqwest::Client,
20 base_url: &str,
21 access_token: &str,
22) -> Result<Me, ClientError> {
23 let url = format!("{base_url}/me");
24 let resp = super::send_with_retry(http.get(&url).bearer_auth(access_token)).await?;
25 let status = resp.status();
26 if !status.is_success() {
27 let text = resp.text().await.unwrap_or_default();
28 return Err(ClientError::Graph {
29 status: status.as_u16(),
30 message: text,
31 });
32 }
33 Ok(resp.json().await?)
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39 use wiremock::matchers::{header, method, path};
40 use wiremock::{Mock, MockServer, ResponseTemplate};
41
42 #[tokio::test]
43 async fn get_me_returns_identity() {
44 let server = MockServer::start().await;
45 Mock::given(method("GET"))
46 .and(path("/me"))
47 .and(header("authorization", "Bearer AT"))
48 .respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
49 "id": "user-id",
50 "userPrincipalName": "kristofer@mklab.se",
51 "displayName": "Kristofer Liljeblad",
52 "mail": "kristofer@mklab.se"
53 })))
54 .mount(&server)
55 .await;
56
57 let http = reqwest::Client::new();
58 let me = get_me(&http, &server.uri(), "AT").await.unwrap();
59 assert_eq!(me.id, "user-id");
60 assert_eq!(me.user_principal_name, "kristofer@mklab.se");
61 }
62}