Remove jwt validation for jschorr to fix later

Refactor oauth validate method to take config over entire appconfig
This commit is contained in:
Sam Chow 2018-06-01 11:31:19 -04:00
parent 7df8ed4a60
commit 301cc6992a
27 changed files with 136 additions and 76 deletions

View file

@ -6,7 +6,6 @@ import urlparse
from abc import ABCMeta, abstractmethod
from six import add_metaclass
from util import get_app_url
from util.config import URLSchemeAndHostname
logger = logging.getLogger(__name__)
@ -74,7 +73,7 @@ class OAuthService(object):
pass
@abstractmethod
def validate_client_id_and_secret(self, http_client, app_config):
def validate_client_id_and_secret(self, http_client, url_scheme_and_hostname):
""" Performs validation of the client ID and secret, raising an exception on failure. """
pass
@ -99,9 +98,10 @@ class OAuthService(object):
"""
return self.config.get('LOGIN_BINDING_FIELD', None)
def get_auth_url(self, app_config, redirect_suffix, csrf_token, scopes):
def get_auth_url(self, url_scheme_and_hostname, redirect_suffix, csrf_token, scopes):
""" Retrieves the authorization URL for this login service. """
redirect_uri = '%s/oauth2/%s/callback%s' % (get_app_url(app_config), self.service_id(),
redirect_uri = '%s/oauth2/%s/callback%s' % (url_scheme_and_hostname.get_url(),
self.service_id(),
redirect_suffix)
params = {
'client_id': self.client_id(),
@ -154,7 +154,7 @@ class OAuthService(object):
def exchange_code(self, app_config, http_client, code, form_encode=False, redirect_suffix='',
client_auth=False):
""" Exchanges an OAuth access code for associated OAuth token and other data. """
url_scheme_and_hostname = URLSchemeAndHostname(app_config['PREFERRED_URL_SCHEME'], app_config['SERVER_HOSTNAME'])
url_scheme_and_hostname = URLSchemeAndHostname.from_app_config(app_config)
payload = {
'code': code,
'grant_type': 'authorization_code',

View file

@ -97,9 +97,9 @@ class OIDCLoginService(OAuthService):
def validate(self):
return bool(self.get_login_scopes())
def validate_client_id_and_secret(self, http_client, app_config):
def validate_client_id_and_secret(self, http_client, url_scheme_and_hostname):
# TODO: find a way to verify client secret too.
check_auth_url = http_client.get(self.get_auth_url(app_config, '', '', []))
check_auth_url = http_client.get(self.get_auth_url(url_scheme_and_hostname, '', '', []))
if check_auth_url.status_code // 100 != 2:
raise Exception('Got non-200 status code for authorization endpoint')

View file

@ -75,8 +75,7 @@ class GithubOAuthService(OAuthLoginService):
def orgs_endpoint(self):
return slash_join(self._api_endpoint(), 'user/orgs')
# TODO(sam): refactor the base method to not take app config
def validate_client_id_and_secret(self, http_client):
def validate_client_id_and_secret(self, http_client, url_scheme_and_hostname):
# First: Verify that the github endpoint is actually Github by checking for the
# X-GitHub-Request-Id here.
api_endpoint = self._api_endpoint()

View file

@ -29,8 +29,6 @@ class GitLabOAuthService(OAuthService):
def token_endpoint(self):
return OAuthEndpoint(slash_join(self._endpoint(), '/oauth/token'))
# TODO(sam): this signature does not match its parent class. refactor the base method to take the namedtuple URLSchemeAndHostname
# TODO cont: reason I did this was to decouple the app, but it requires more refactoring
def validate_client_id_and_secret(self, http_client, url_scheme_and_hostname):
# We validate the client ID and secret by hitting the OAuth token exchange endpoint with
# the real client ID and secret, but a fake auth code to exchange. Gitlab's implementation will

View file

@ -41,8 +41,7 @@ class GoogleOAuthService(OAuthLoginService):
def requires_form_encoding(self):
return True
# TODO(sam): this signature does not match its parent class. refactor the base method to take the namedtuple URLSchemeAndHostname
def validate_client_id_and_secret(self, http_client):
def validate_client_id_and_secret(self, http_client, url_scheme_and_hostname):
# 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

View file

@ -13,6 +13,8 @@ from Crypto.PublicKey import RSA
from jwkest.jwk import RSAKey
from oauth.oidc import OIDCLoginService, OAuthLoginException
from util.config import URLSchemeAndHostname
@pytest.fixture(scope='module') # Slow to generate, only do it once.
def signing_key():
@ -277,7 +279,8 @@ def test_auth_url(oidc_service, discovery_handler, http_client, authorize_handle
config = {'PREFERRED_URL_SCHEME': 'https', 'SERVER_HOSTNAME': 'someserver'}
with HTTMock(discovery_handler, authorize_handler):
auth_url = oidc_service.get_auth_url(config, '', 'some csrf token', ['one', 'two'])
url_scheme_and_hostname = URLSchemeAndHostname.from_app_config(config)
auth_url = oidc_service.get_auth_url(url_scheme_and_hostname, '', 'some csrf token', ['one', 'two'])
# Hit the URL and ensure it works.
result = http_client.get(auth_url).json()