forked from mirror/django-mailbox
111 lines
3 KiB
Python
111 lines
3 KiB
Python
import logging
|
|
|
|
from django.conf import settings
|
|
import requests
|
|
from social.apps.django_app.default.models import UserSocialAuth
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class AccessTokenNotFound(Exception):
|
|
pass
|
|
|
|
|
|
class RefreshTokenNotFound(Exception):
|
|
pass
|
|
|
|
|
|
def get_google_consumer_key():
|
|
return settings.SOCIAL_AUTH_GOOGLE_OAUTH2_KEY
|
|
|
|
|
|
def get_google_consumer_secret():
|
|
return settings.SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET
|
|
|
|
|
|
def get_google_access_token(email):
|
|
# TODO: This should be cacheable
|
|
try:
|
|
me = UserSocialAuth.objects.get(uid=email, provider="google-oauth2")
|
|
return me.extra_data['access_token']
|
|
except (UserSocialAuth.DoesNotExist, KeyError):
|
|
raise AccessTokenNotFound
|
|
|
|
|
|
def update_google_extra_data(email, extra_data):
|
|
try:
|
|
me = UserSocialAuth.objects.get(uid=email, provider="google-oauth2")
|
|
me.extra_data = extra_data
|
|
me.save()
|
|
except (UserSocialAuth.DoesNotExist, KeyError):
|
|
raise AccessTokenNotFound
|
|
|
|
|
|
def get_google_refresh_token(email):
|
|
try:
|
|
me = UserSocialAuth.objects.get(uid=email, provider="google-oauth2")
|
|
return me.extra_data['refresh_token']
|
|
except (UserSocialAuth.DoesNotExist, KeyError):
|
|
raise RefreshTokenNotFound
|
|
|
|
|
|
def google_api_get(email, url):
|
|
headers = dict(
|
|
Authorization="Bearer %s" % get_google_access_token(email),
|
|
)
|
|
r = requests.get(url, headers=headers)
|
|
logger.info("I got a %s", r.status_code)
|
|
if r.status_code == 401:
|
|
# Go use the refresh token
|
|
refresh_authorization(email)
|
|
r = requests.get(url, headers=headers)
|
|
logger.info("I got a %s", r.status_code)
|
|
if r.status_code == 200:
|
|
try:
|
|
return r.json()
|
|
except ValueError:
|
|
return r.text
|
|
|
|
|
|
def google_api_post(email, url, post_data, authorized=True):
|
|
# TODO: Make this a lot less ugly. especially the 401 handling
|
|
headers = dict()
|
|
if authorized is True:
|
|
headers.update(dict(
|
|
Authorization="Bearer %s" % get_google_access_token(email),
|
|
))
|
|
r = requests.post(url, headers=headers, data=post_data)
|
|
if r.status_code == 401:
|
|
refresh_authorization(email)
|
|
r = requests.post(url, headers=headers, data=post_data)
|
|
if r.status_code == 200:
|
|
try:
|
|
return r.json()
|
|
except ValueError:
|
|
return r.text
|
|
|
|
|
|
def refresh_authorization(email):
|
|
refresh_token = get_google_refresh_token(email)
|
|
post_data = dict(
|
|
refresh_token=refresh_token,
|
|
client_id=get_google_consumer_key(),
|
|
client_secret=get_google_consumer_secret(),
|
|
grant_type='refresh_token',
|
|
)
|
|
results = google_api_post(
|
|
email,
|
|
"https://accounts.google.com/o/oauth2/token?access_type=offline",
|
|
post_data,
|
|
authorized=False)
|
|
results.update({'refresh_token': refresh_token})
|
|
update_google_extra_data(email, results)
|
|
|
|
|
|
def fetch_user_info(email):
|
|
result = google_api_get(
|
|
email,
|
|
"https://www.googleapis.com/oauth2/v1/userinfo?alt=json"
|
|
)
|
|
return result
|