userp/oauth/provider/
spotify.rs

1use super::custom::OAuthCustomProvider;
2use crate::oauth::OAuthProviderUser;
3use anyhow::Context;
4use serde_json::Value;
5
6pub struct SpotifyOAuthProvider;
7
8impl SpotifyOAuthProvider {
9    #[allow(clippy::new_ret_no_self)]
10    pub fn new(
11        client_id: impl Into<String>,
12        client_secret: impl Into<String>,
13    ) -> OAuthCustomProvider {
14        OAuthCustomProvider::new_with_callback(
15            "spotify",
16            "Spotify",
17            client_id,
18            client_secret,
19            "https://accounts.spotify.com/authorize",
20            "https://accounts.spotify.com/api/token",
21            &["user-read-email"],
22            |access_token| async move {
23                let client = reqwest::Client::new();
24
25                let res = client
26                    .get("https://api.spotify.com/v1/me")
27                    .header("Accept", "application/json")
28                    .bearer_auth(access_token)
29                    .send()
30                    .await?
31                    .json::<Value>()
32                    .await?;
33
34                let id = res
35                    .as_object()
36                    .and_then(|obj| obj.get("id").and_then(|id| id.as_str()))
37                    .context("Missing id")?
38                    .to_string();
39
40                let email = res
41                    .as_object()
42                    .and_then(|obj| obj.get("email").and_then(|id| id.as_str()))
43                    .map(|name| name.to_string());
44
45                let name = res
46                    .as_object()
47                    .and_then(|obj| obj.get("display_name").and_then(|id| id.as_str()))
48                    .map(|name| name.to_string());
49
50                Ok(OAuthProviderUser {
51                    id,
52                    email,
53                    name,
54                    email_verified: false,
55                })
56            },
57        )
58        .expect("Built in providers should work")
59    }
60}