Skip to main content

simple_oauth/common/
facebook.rs

1use serde::Deserialize;
2
3use crate::{
4    SimpleOAuthProvider, UserInfoProvider,
5    types::{TokenAuthMethod, UserInfo},
6};
7
8#[derive(Debug, Clone)]
9pub struct Facebook;
10
11/// User info returned from Facebook Graph API
12#[derive(Debug, Deserialize)]
13struct FacebookUserInfo {
14    id: String,
15    name: Option<String>,
16    email: Option<String>,
17    picture: Option<FacebookPicture>,
18}
19
20#[derive(Debug, Deserialize)]
21struct FacebookPicture {
22    data: Option<FacebookPictureData>,
23}
24
25#[derive(Debug, Deserialize)]
26struct FacebookPictureData {
27    url: Option<String>,
28}
29
30impl SimpleOAuthProvider for Facebook {
31    fn authorize_url(&self) -> &str {
32        "https://www.facebook.com/dialog/oauth"
33    }
34
35    fn token_url(&self) -> &str {
36        "https://graph.facebook.com/oauth/access_token"
37    }
38
39    fn default_scopes(&self) -> &'static [&'static str] {
40        &["public_profile"]
41    }
42
43    fn token_auth_method(&self) -> TokenAuthMethod {
44        TokenAuthMethod::RequestBody
45    }
46}
47
48impl UserInfoProvider for Facebook {
49    fn user_info_url(&self) -> &str {
50        "https://graph.facebook.com/me?fields=id,name,email,picture"
51    }
52
53    fn extract_user_info(&self, val: serde_json::Value) -> Result<UserInfo, serde_json::Error> {
54        let user_info: FacebookUserInfo = serde_json::from_value(val)?;
55        let avatar_url = user_info
56            .picture
57            .and_then(|picture| picture.data)
58            .and_then(|data| data.url);
59
60        Ok(UserInfo {
61            id: user_info.id,
62            name: user_info.name,
63            email: user_info.email,
64            avatar_url,
65            ..Default::default()
66        })
67    }
68}