52 lines
1.6 KiB
Python
52 lines
1.6 KiB
Python
from typing import Any
|
|
|
|
from .base import OAuthProvider
|
|
|
|
|
|
class GitHubOAuthProvider(OAuthProvider):
|
|
"""GitHub OAuth provider implementation."""
|
|
|
|
@property
|
|
def name(self) -> str:
|
|
return "github"
|
|
|
|
@property
|
|
def display_name(self) -> str:
|
|
return "GitHub"
|
|
|
|
def get_client_config(self) -> dict[str, Any]:
|
|
"""Return GitHub OAuth client configuration."""
|
|
return {
|
|
"access_token_url": "https://github.com/login/oauth/access_token",
|
|
"authorize_url": "https://github.com/login/oauth/authorize",
|
|
"api_base_url": "https://api.github.com/",
|
|
"client_kwargs": {"scope": "user:email"},
|
|
}
|
|
|
|
def get_user_info(self, token: dict[str, Any]) -> dict[str, Any]:
|
|
"""Extract user information from GitHub OAuth token response."""
|
|
client = self.get_client()
|
|
|
|
# Get user profile
|
|
user_resp = client.get("user", token=token)
|
|
user_data = user_resp.json()
|
|
|
|
# Get user email (may be private)
|
|
email = user_data.get("email")
|
|
if not email:
|
|
# If email is private, get from emails endpoint
|
|
emails_resp = client.get("user/emails", token=token)
|
|
emails = emails_resp.json()
|
|
# Find primary email
|
|
for email_obj in emails:
|
|
if email_obj.get("primary", False):
|
|
email = email_obj.get("email")
|
|
break
|
|
|
|
return {
|
|
"id": str(user_data.get("id")),
|
|
"email": email,
|
|
"name": user_data.get("name") or user_data.get("login"),
|
|
"picture": user_data.get("avatar_url"),
|
|
}
|