Source code for solo.apps.accounts.providers.facebook
import logging
from typing import List, Optional
from aiohttp import ClientSession
from aiohttp import web
from solo.apps.accounts.model import AuthProvider
from solo.apps.accounts.exceptions import ProviderServiceError
from .base_oauth2 import OAuth2Provider, ThirdPartyProfile, ProfileIntegration
log = logging.getLogger(__name__)
[docs]@AuthProvider.FACEBOOK.bind(AuthProvider.Contract.auth_provider_impl)
class FacebookProvider(OAuth2Provider):
""" Facebook OAuth2 provider.
* Application management: https://developers.facebook.com/apps/
* API reference: https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow
"""
def __init__(self, client_id: str, client_secret: str, scope: List[str], redirect_uri: Optional[str] = None):
"""
:param redirect_uri: The redirect_uri parameter is optional. If left out, GitHub will redirect users to the
callback URL configured in the OAuth Application settings.
"""
super(FacebookProvider, self).__init__(client_id, client_secret, scope,
redirect_uri=redirect_uri,
authorize_url='https://www.facebook.com/dialog/oauth',
access_token_url='https://graph.facebook.com/v2.6/oauth/access_token',
profile_url='https://graph.facebook.com/v2.6/me')
async def callback(self, request: web.Request) -> ProfileIntegration:
""" Process github redirect
"""
session_state, code = await self.validate_callback(request)
# Now retrieve the access token with the code
access_url = self.get_access_token_payload(session_state, code)
with ClientSession(headers={'Accept': 'application/json'}) as http:
async with http.get(access_url) as r:
if r.status != 200:
content = await r.text()
raise ProviderServiceError('Service responded with status {}: {}'.format(r.status, content))
else:
content = await r.json()
access_token = content['access_token']
# Retrieve profile data
profile_url = self.get_profile_payload(access_token=access_token)
async with http.get(profile_url) as profile_r:
if profile_r.status != 200:
content = await profile_r.text()
raise ProviderServiceError("Error during profile retrieval. Status {}: {}".format(
profile_r.status,
content
))
else:
profile_data = await profile_r.json()
profile = ThirdPartyProfile(id=str(profile_data['id']),
display_name=profile_data['name'],
# email might be non-verified
email=profile_data.get('email'))
return ProfileIntegration(provider=AuthProvider.FACEBOOK,
access_token=access_token,
profile=profile)