diff --git a/oauth/base.py b/oauth/base.py index 15a82c1c4..ee290bbf5 100644 --- a/oauth/base.py +++ b/oauth/base.py @@ -1,6 +1,9 @@ import logging import urllib +from abc import ABCMeta, abstractmethod +from six import add_metaclass + from util import get_app_url logger = logging.getLogger(__name__) @@ -13,36 +16,43 @@ class OAuthGetUserInfoException(Exception): """ Exception raised if a call to get user information fails. """ pass +@add_metaclass(ABCMeta) class OAuthService(object): """ A base class for defining an external service, exposed via OAuth. """ def __init__(self, config, key_name): self.key_name = key_name self.config = config.get(key_name) or {} + @abstractmethod def service_id(self): """ 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): """ The user-readable name for the service, e.g. `GitHub`""" - raise NotImplementedError + pass + @abstractmethod def token_endpoint(self): """ The endpoint at which the OAuth code can be exchanged for a token. """ - raise NotImplementedError + pass + @abstractmethod def user_endpoint(self): """ 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): """ Performs validation of the client ID and secret, raising an exception on failure. """ - raise NotImplementedError + pass + @abstractmethod def authorize_endpoint(self): """ Endpoint for authorization. """ - raise NotImplementedError + pass def requires_form_encoding(self): """ Returns True if form encoding is necessary for the exchange_code_for_token call. """ diff --git a/oauth/login.py b/oauth/login.py index 268d030f7..55c94be69 100644 --- a/oauth/login.py +++ b/oauth/login.py @@ -1,5 +1,8 @@ import logging +from abc import ABCMeta, abstractmethod +from six import add_metaclass + import features from oauth.base import OAuthService, OAuthExchangeCodeException, OAuthGetUserInfoException @@ -10,33 +13,41 @@ class OAuthLoginException(Exception): """ Exception raised if a login operation fails. """ pass + +@add_metaclass(ABCMeta) class OAuthLoginService(OAuthService): """ A base class for defining an OAuth-compliant service that can be used for, amongst other things, login and authentication. """ + @abstractmethod def login_enabled(self): """ Returns true if the login service is enabled. """ - raise NotImplementedError + pass + @abstractmethod def get_login_service_id(self, user_info): """ Returns the internal ID for the given user under this login service. """ - raise NotImplementedError + pass + @abstractmethod def get_login_service_username(self, user_info): """ 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): """ Returns the verified email address for the given user, if any or None if none. """ - raise NotImplementedError + pass + @abstractmethod def get_icon(self): """ Returns the icon to display for this login service. """ - raise NotImplementedError + pass + @abstractmethod def get_login_scopes(self): """ 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): """ Performs service-specific verification of user information for login. On failure, a service