Switch base classes in OAuth to use ABC

This commit is contained in:
Joseph Schorr 2017-01-24 15:20:03 -05:00
parent a9791ea419
commit adb2ff0b81
2 changed files with 33 additions and 12 deletions

View file

@ -1,6 +1,9 @@
import logging import logging
import urllib import urllib
from abc import ABCMeta, abstractmethod
from six import add_metaclass
from util import get_app_url from util import get_app_url
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -13,36 +16,43 @@ class OAuthGetUserInfoException(Exception):
""" Exception raised if a call to get user information fails. """ """ Exception raised if a call to get user information fails. """
pass pass
@add_metaclass(ABCMeta)
class OAuthService(object): class OAuthService(object):
""" A base class for defining an external service, exposed via OAuth. """ """ A base class for defining an external service, exposed via OAuth. """
def __init__(self, config, key_name): def __init__(self, config, key_name):
self.key_name = key_name self.key_name = key_name
self.config = config.get(key_name) or {} self.config = config.get(key_name) or {}
@abstractmethod
def service_id(self): def service_id(self):
""" The internal ID for this service. Must match the URL portion for the service, e.g. `github` """ The internal ID for this service. Must match the URL portion for the service, e.g. `github`
""" """
raise NotImplementedError pass
@abstractmethod
def service_name(self): def service_name(self):
""" The user-readable name for the service, e.g. `GitHub`""" """ The user-readable name for the service, e.g. `GitHub`"""
raise NotImplementedError pass
@abstractmethod
def token_endpoint(self): def token_endpoint(self):
""" The endpoint at which the OAuth code can be exchanged for a token. """ """ The endpoint at which the OAuth code can be exchanged for a token. """
raise NotImplementedError pass
@abstractmethod
def user_endpoint(self): def user_endpoint(self):
""" The endpoint at which user information can be looked up. """ """ The endpoint at which user information can be looked up. """
raise NotImplementedError pass
@abstractmethod
def validate_client_id_and_secret(self, http_client, app_config): def validate_client_id_and_secret(self, http_client, app_config):
""" Performs validation of the client ID and secret, raising an exception on failure. """ """ Performs validation of the client ID and secret, raising an exception on failure. """
raise NotImplementedError pass
@abstractmethod
def authorize_endpoint(self): def authorize_endpoint(self):
""" Endpoint for authorization. """ """ Endpoint for authorization. """
raise NotImplementedError pass
def requires_form_encoding(self): def requires_form_encoding(self):
""" Returns True if form encoding is necessary for the exchange_code_for_token call. """ """ Returns True if form encoding is necessary for the exchange_code_for_token call. """

View file

@ -1,5 +1,8 @@
import logging import logging
from abc import ABCMeta, abstractmethod
from six import add_metaclass
import features import features
from oauth.base import OAuthService, OAuthExchangeCodeException, OAuthGetUserInfoException from oauth.base import OAuthService, OAuthExchangeCodeException, OAuthGetUserInfoException
@ -10,33 +13,41 @@ class OAuthLoginException(Exception):
""" Exception raised if a login operation fails. """ """ Exception raised if a login operation fails. """
pass pass
@add_metaclass(ABCMeta)
class OAuthLoginService(OAuthService): class OAuthLoginService(OAuthService):
""" A base class for defining an OAuth-compliant service that can be used for, amongst other """ A base class for defining an OAuth-compliant service that can be used for, amongst other
things, login and authentication. """ things, login and authentication. """
@abstractmethod
def login_enabled(self): def login_enabled(self):
""" Returns true if the login service is enabled. """ """ Returns true if the login service is enabled. """
raise NotImplementedError pass
@abstractmethod
def get_login_service_id(self, user_info): def get_login_service_id(self, user_info):
""" Returns the internal ID for the given user under this login service. """ """ Returns the internal ID for the given user under this login service. """
raise NotImplementedError pass
@abstractmethod
def get_login_service_username(self, user_info): def get_login_service_username(self, user_info):
""" Returns the username for the given user under this login service. """ """ Returns the username for the given user under this login service. """
raise NotImplementedError pass
@abstractmethod
def get_verified_user_email(self, app_config, http_client, token, user_info): def get_verified_user_email(self, app_config, http_client, token, user_info):
""" Returns the verified email address for the given user, if any or None if none. """ """ Returns the verified email address for the given user, if any or None if none. """
raise NotImplementedError pass
@abstractmethod
def get_icon(self): def get_icon(self):
""" Returns the icon to display for this login service. """ """ Returns the icon to display for this login service. """
raise NotImplementedError pass
@abstractmethod
def get_login_scopes(self): def get_login_scopes(self):
""" Returns the list of scopes for login for this service. """ """ Returns the list of scopes for login for this service. """
raise NotImplementedError pass
def service_verify_user_info_for_login(self, app_config, http_client, token, user_info): def service_verify_user_info_for_login(self, app_config, http_client, token, user_info):
""" Performs service-specific verification of user information for login. On failure, a service """ Performs service-specific verification of user information for login. On failure, a service