Fix bug with missing & in authorization URL for OIDC
Also adds testing to ensure we don't break this again
This commit is contained in:
parent
4c0ab81ac8
commit
22a39c3007
8 changed files with 131 additions and 86 deletions
|
@ -1,5 +1,6 @@
|
|||
import logging
|
||||
|
||||
from oauth.base import OAuthEndpoint
|
||||
from oauth.login import OAuthLoginService, OAuthLoginException
|
||||
from util import slash_join
|
||||
|
||||
|
@ -50,10 +51,13 @@ class GithubOAuthService(OAuthLoginService):
|
|||
return self._api_endpoint().find('.github.com') < 0
|
||||
|
||||
def authorize_endpoint(self):
|
||||
return slash_join(self._endpoint(), '/login/oauth/authorize') + '?'
|
||||
return OAuthEndpoint(slash_join(self._endpoint(), '/login/oauth/authorize'))
|
||||
|
||||
def token_endpoint(self):
|
||||
return slash_join(self._endpoint(), '/login/oauth/access_token')
|
||||
return OAuthEndpoint(slash_join(self._endpoint(), '/login/oauth/access_token'))
|
||||
|
||||
def user_endpoint(self):
|
||||
return OAuthEndpoint(slash_join(self._api_endpoint(), 'user'))
|
||||
|
||||
def _api_endpoint(self):
|
||||
return self.config.get('API_ENDPOINT', slash_join(self._endpoint(), '/api/v3/'))
|
||||
|
@ -65,9 +69,6 @@ class GithubOAuthService(OAuthLoginService):
|
|||
|
||||
return endpoint
|
||||
|
||||
def user_endpoint(self):
|
||||
return slash_join(self._api_endpoint(), 'user')
|
||||
|
||||
def email_endpoint(self):
|
||||
return slash_join(self._api_endpoint(), 'user/emails')
|
||||
|
||||
|
@ -112,7 +113,7 @@ class GithubOAuthService(OAuthLoginService):
|
|||
def get_public_config(self):
|
||||
return {
|
||||
'CLIENT_ID': self.client_id(),
|
||||
'AUTHORIZE_ENDPOINT': self.authorize_endpoint(),
|
||||
'AUTHORIZE_ENDPOINT': self.authorize_endpoint().to_url_prefix(),
|
||||
'GITHUB_ENDPOINT': self._endpoint(),
|
||||
'ORG_RESTRICT': self.config.get('ORG_RESTRICT', False)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from oauth.base import OAuthService
|
||||
from oauth.base import OAuthService, OAuthEndpoint
|
||||
from util import slash_join
|
||||
|
||||
class GitLabOAuthService(OAuthService):
|
||||
|
@ -24,17 +24,17 @@ class GitLabOAuthService(OAuthService):
|
|||
return slash_join(self._endpoint(), suffix)
|
||||
|
||||
def authorize_endpoint(self):
|
||||
return slash_join(self._endpoint(), '/oauth/authorize')
|
||||
return OAuthEndpoint(slash_join(self._endpoint(), '/oauth/authorize'))
|
||||
|
||||
def token_endpoint(self):
|
||||
return slash_join(self._endpoint(), '/oauth/token')
|
||||
return OAuthEndpoint(slash_join(self._endpoint(), '/oauth/token'))
|
||||
|
||||
def validate_client_id_and_secret(self, http_client, app_config):
|
||||
# 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
|
||||
# return `invalid_client` as the `error` if the client ID or secret is invalid; otherwise, it
|
||||
# will return another error.
|
||||
url = self.token_endpoint()
|
||||
url = self.token_endpoint().to_url()
|
||||
redirect_uri = self.get_redirect_uri(app_config, redirect_suffix='trigger')
|
||||
data = {
|
||||
'code': 'fakecode',
|
||||
|
@ -55,6 +55,6 @@ class GitLabOAuthService(OAuthService):
|
|||
def get_public_config(self):
|
||||
return {
|
||||
'CLIENT_ID': self.client_id(),
|
||||
'AUTHORIZE_ENDPOINT': self.authorize_endpoint(),
|
||||
'AUTHORIZE_ENDPOINT': self.authorize_endpoint().to_url_prefix(),
|
||||
'GITLAB_ENDPOINT': self._endpoint(),
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from oauth.base import OAuthEndpoint
|
||||
from oauth.login import OAuthLoginService
|
||||
|
||||
def _get_email_username(email_address):
|
||||
|
@ -28,13 +29,14 @@ class GoogleOAuthService(OAuthLoginService):
|
|||
return ['openid', 'email']
|
||||
|
||||
def authorize_endpoint(self):
|
||||
return 'https://accounts.google.com/o/oauth2/auth?response_type=code&'
|
||||
return OAuthEndpoint('https://accounts.google.com/o/oauth2/auth',
|
||||
params=dict(response_type='code'))
|
||||
|
||||
def token_endpoint(self):
|
||||
return 'https://accounts.google.com/o/oauth2/token'
|
||||
return OAuthEndpoint('https://accounts.google.com/o/oauth2/token')
|
||||
|
||||
def user_endpoint(self):
|
||||
return 'https://www.googleapis.com/oauth2/v1/userinfo'
|
||||
return OAuthEndpoint('https://www.googleapis.com/oauth2/v1/userinfo')
|
||||
|
||||
def requires_form_encoding(self):
|
||||
return True
|
||||
|
@ -59,7 +61,7 @@ class GoogleOAuthService(OAuthLoginService):
|
|||
def get_public_config(self):
|
||||
return {
|
||||
'CLIENT_ID': self.client_id(),
|
||||
'AUTHORIZE_ENDPOINT': self.authorize_endpoint()
|
||||
'AUTHORIZE_ENDPOINT': self.authorize_endpoint().to_url_prefix()
|
||||
}
|
||||
|
||||
def get_login_service_id(self, user_info):
|
||||
|
|
39
oauth/services/test/test_github.py
Normal file
39
oauth/services/test/test_github.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
import pytest
|
||||
|
||||
from oauth.services.github import GithubOAuthService
|
||||
|
||||
@pytest.mark.parametrize('trigger_config, domain, api_endpoint, is_enterprise', [
|
||||
({
|
||||
'CLIENT_ID': 'someclientid',
|
||||
'CLIENT_SECRET': 'someclientsecret',
|
||||
'API_ENDPOINT': 'https://api.github.com/v3',
|
||||
}, 'https://github.com', 'https://api.github.com/v3', False),
|
||||
({
|
||||
'GITHUB_ENDPOINT': 'https://github.somedomain.com/',
|
||||
'CLIENT_ID': 'someclientid',
|
||||
'CLIENT_SECRET': 'someclientsecret',
|
||||
}, 'https://github.somedomain.com', 'https://github.somedomain.com/api/v3', True),
|
||||
({
|
||||
'GITHUB_ENDPOINT': 'https://github.somedomain.com/',
|
||||
'API_ENDPOINT': 'http://somedomain.com/api/',
|
||||
'CLIENT_ID': 'someclientid',
|
||||
'CLIENT_SECRET': 'someclientsecret',
|
||||
}, 'https://github.somedomain.com', 'http://somedomain.com/api', True),
|
||||
])
|
||||
def test_basic_enterprise_config(trigger_config, domain, api_endpoint, is_enterprise):
|
||||
config = {
|
||||
'GITHUB_TRIGGER_CONFIG': trigger_config
|
||||
}
|
||||
|
||||
github_trigger = GithubOAuthService(config, 'GITHUB_TRIGGER_CONFIG')
|
||||
assert github_trigger.is_enterprise() == is_enterprise
|
||||
|
||||
assert github_trigger.authorize_endpoint().to_url() == '%s/login/oauth/authorize' % domain
|
||||
assert github_trigger.authorize_endpoint().to_url_prefix() == '%s/login/oauth/authorize?' % domain
|
||||
|
||||
assert github_trigger.token_endpoint().to_url() == '%s/login/oauth/access_token' % domain
|
||||
|
||||
assert github_trigger.api_endpoint() == api_endpoint
|
||||
assert github_trigger.user_endpoint().to_url() == '%s/user' % api_endpoint
|
||||
assert github_trigger.email_endpoint() == '%s/user/emails' % api_endpoint
|
||||
assert github_trigger.orgs_endpoint() == '%s/user/orgs' % api_endpoint
|
Reference in a new issue