Remove jwt validation for jschorr to fix later
Refactor oauth validate method to take config over entire appconfig
This commit is contained in:
parent
7df8ed4a60
commit
301cc6992a
27 changed files with 136 additions and 76 deletions
|
@ -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',
|
||||
|
|
|
@ -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')
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
Reference in a new issue