Lay foundation for truly dynamic external logins
Moves all the external login services into a set of classes that share as much code as possible. These services are then registered on both the client and server, allowing us in the followup change to dynamically register new handlers
This commit is contained in:
parent
4755d08677
commit
19f7acf575
26 changed files with 686 additions and 472 deletions
76
oauth/services/google.py
Normal file
76
oauth/services/google.py
Normal file
|
@ -0,0 +1,76 @@
|
|||
from oauth.login import OAuthLoginService
|
||||
|
||||
def _get_email_username(email_address):
|
||||
username = email_address
|
||||
at = username.find('@')
|
||||
if at > 0:
|
||||
username = username[0:at]
|
||||
|
||||
return username
|
||||
|
||||
class GoogleOAuthService(OAuthLoginService):
|
||||
def __init__(self, config, key_name):
|
||||
super(GoogleOAuthService, self).__init__(config, key_name)
|
||||
|
||||
def service_id(self):
|
||||
return 'google'
|
||||
|
||||
def service_name(self):
|
||||
return 'Google'
|
||||
|
||||
def get_icon(self):
|
||||
return 'fa-google'
|
||||
|
||||
def get_login_scopes(self):
|
||||
return ['openid', 'email']
|
||||
|
||||
def authorize_endpoint(self):
|
||||
return 'https://accounts.google.com/o/oauth2/auth?response_type=code&'
|
||||
|
||||
def token_endpoint(self):
|
||||
return 'https://accounts.google.com/o/oauth2/token'
|
||||
|
||||
def user_endpoint(self):
|
||||
return 'https://www.googleapis.com/oauth2/v1/userinfo'
|
||||
|
||||
def requires_form_encoding(self):
|
||||
return True
|
||||
|
||||
def validate_client_id_and_secret(self, http_client, app_config):
|
||||
# To verify the Google client ID and secret, we hit the
|
||||
# https://www.googleapis.com/oauth2/v3/token endpoint with an invalid request. If the client
|
||||
# ID or secret are invalid, we get returned a 403 Unauthorized. Otherwise, we get returned
|
||||
# another response code.
|
||||
url = 'https://www.googleapis.com/oauth2/v3/token'
|
||||
data = {
|
||||
'code': 'fakecode',
|
||||
'client_id': self.client_id(),
|
||||
'client_secret': self.client_secret(),
|
||||
'grant_type': 'authorization_code',
|
||||
'redirect_uri': 'http://example.com'
|
||||
}
|
||||
|
||||
result = http_client.post(url, data=data, timeout=5)
|
||||
return result.status_code != 401
|
||||
|
||||
def get_public_config(self):
|
||||
return {
|
||||
'CLIENT_ID': self.client_id(),
|
||||
'AUTHORIZE_ENDPOINT': self.authorize_endpoint()
|
||||
}
|
||||
|
||||
def get_login_service_id(self, user_info):
|
||||
return user_info['id']
|
||||
|
||||
def get_login_service_username(self, user_info):
|
||||
return _get_email_username(user_info['email'])
|
||||
|
||||
def get_verified_user_email(self, app_config, http_client, token, user_info):
|
||||
if not user_info.get('verified_email', False):
|
||||
return None
|
||||
|
||||
return user_info['email']
|
||||
|
||||
def service_verify_user_info_for_login(self, app_config, http_client, token, user_info):
|
||||
# Nothing to do.
|
||||
pass
|
Reference in a new issue