Skip to main content

simple_oauth/common/
github.rs

1use serde::Deserialize;
2
3use crate::{SimpleOAuthProvider, types::UserInfo};
4
5#[derive(Debug, Clone)]
6pub struct GitHub;
7
8/// User info returned from GitHub API
9#[derive(Debug, Deserialize)]
10struct GitHubUserInfo {
11    id: u64,
12    login: String,
13    name: Option<String>,
14    email: Option<String>,
15    avatar_url: Option<String>,
16}
17
18impl SimpleOAuthProvider for GitHub {
19    fn authorize_url(&self) -> &str {
20        "https://github.com/login/oauth/authorize"
21    }
22
23    fn token_url(&self) -> &str {
24        "https://github.com/login/oauth/access_token"
25    }
26
27    fn default_scopes(&self) -> &'static [&'static str] {
28        &["read:user"]
29    }
30
31    fn user_info_url(&self) -> &str {
32        "https://api.github.com/user"
33    }
34
35    fn additional_headers(&self) -> Vec<(String, String)> {
36        vec![
37            ("Accept".into(), "application/vnd.github+json".into()),
38            ("User-Agent".into(), "fa-sharp/simple-oauth".into()),
39        ]
40    }
41
42    fn extract_user_info(
43        &self,
44        user_info: serde_json::Value,
45    ) -> Result<UserInfo, serde_json::Error> {
46        let info: GitHubUserInfo = serde_json::from_value(user_info)?;
47
48        Ok(UserInfo {
49            id: info.id.to_string(),
50            name: info.name,
51            username: Some(info.login),
52            email: info.email,
53            email_verified: None,
54            avatar_url: info.avatar_url,
55            ..Default::default()
56        })
57    }
58}