Merge pull request #1092 from jzelinskie/gitlab
Allow for custom Gitlab host
This commit is contained in:
commit
408ac90346
6 changed files with 62 additions and 38 deletions
|
@ -1,8 +1,9 @@
|
|||
import logging
|
||||
|
||||
from functools import wraps
|
||||
from urlparse import urljoin
|
||||
|
||||
from app import app
|
||||
from app import app, gitlab_trigger
|
||||
|
||||
from jsonschema import validate
|
||||
from buildtrigger.triggerutil import (RepositoryReadException, TriggerActivationException,
|
||||
|
@ -127,9 +128,8 @@ class GitLabBuildTrigger(BuildTriggerHandler):
|
|||
return 'gitlab'
|
||||
|
||||
def _get_authorized_client(self):
|
||||
host = app.config.get('GITLAB_TRIGGER_CONFIG', {}).get('GITLAB_ENDPOINT', '')
|
||||
auth_token = self.auth_token or 'invalid'
|
||||
return gitlab.Gitlab(host, oauth_token=auth_token, timeout=5)
|
||||
return gitlab.Gitlab(gitlab_trigger.api_endpoint(), oauth_token=auth_token, timeout=5)
|
||||
|
||||
def is_active(self):
|
||||
return 'hook_id' in self.config
|
||||
|
@ -318,7 +318,7 @@ class GitLabBuildTrigger(BuildTriggerHandler):
|
|||
return None
|
||||
|
||||
def get_repository_url(self):
|
||||
return 'https://gitlab.com/%s' % self.config['build_source']
|
||||
return gitlab_trigger.get_public_url(self.config['build_source'])
|
||||
|
||||
@_catch_timeouts
|
||||
def lookup_user(self, email):
|
||||
|
|
|
@ -116,6 +116,9 @@ class DefaultConfig(object):
|
|||
# Bitbucket Config.
|
||||
BITBUCKET_TRIGGER_CONFIG = None
|
||||
|
||||
# Gitlab Config.
|
||||
GITLAB_TRIGGER_CONFIG = None
|
||||
|
||||
# Requests based HTTP client with a large request pool
|
||||
HTTPCLIENT = build_requests_session()
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ from semantic_version import Version, Spec
|
|||
from util.validation import generate_valid_usernames
|
||||
from util.registry.generatorfile import GeneratorFile
|
||||
from util.registry.dockerver import docker_version
|
||||
from util.string import slash_join
|
||||
|
||||
class TestGeneratorFile(unittest.TestCase):
|
||||
def sample_generator(self):
|
||||
|
@ -174,6 +175,21 @@ class TestDockerVersionParsing(unittest.TestCase):
|
|||
self.assertTrue(spec.match(Version(match_case)),
|
||||
'Spec: %s Case: %s' % (spec, match_case))
|
||||
|
||||
|
||||
class TestSlashJoining(unittest.TestCase):
|
||||
def test_joining(self):
|
||||
test_cases = [
|
||||
(['https://github.com', '/coreos-inc/' 'quay/pull/1092/files'],
|
||||
'https://github.com/coreos-inc/quay/pull/1092/files'),
|
||||
(['https://', 'github.com/', '/coreos-inc', '/quay/pull/1092/files/'],
|
||||
'https://github.com/coreos-inc/quay/pull/1092/files'),
|
||||
]
|
||||
|
||||
for args, url in test_cases:
|
||||
joined_url = slash_join(*args)
|
||||
self.assertEquals(url, joined_url)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
def get_app_url(config):
|
||||
""" Returns the application's URL, based on the given config. """
|
||||
return '%s://%s' % (config['PREFERRED_URL_SCHEME'], config['SERVER_HOSTNAME'])
|
||||
|
||||
|
||||
def slash_join(*args):
|
||||
"""
|
||||
Joins together strings and guarantees there is only one '/' in between the
|
||||
each string joined. Double slashes ('//') are assumed to be intentional and
|
||||
are not deduplicated.
|
||||
"""
|
||||
def rmslash(path):
|
||||
path = path[1:] if path[0] == '/' else path
|
||||
path = path[:-1] if path[-1] == '/' else path
|
||||
return path
|
||||
|
||||
args = [rmslash(path) for path in args]
|
||||
return '/'.join(args)
|
||||
|
|
|
@ -5,6 +5,7 @@ import time
|
|||
|
||||
from cachetools import TTLCache
|
||||
from jwkest.jwk import KEYS
|
||||
from util import slash_join
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -31,12 +32,6 @@ class OAuthConfig(object):
|
|||
def client_secret(self):
|
||||
return self.config.get('CLIENT_SECRET')
|
||||
|
||||
def _get_url(self, endpoint, *args):
|
||||
for arg in args:
|
||||
endpoint = urlparse.urljoin(endpoint, arg)
|
||||
|
||||
return endpoint
|
||||
|
||||
def get_redirect_uri(self, app_config, redirect_suffix=''):
|
||||
return '%s://%s/oauth2/%s/callback%s' % (app_config['PREFERRED_URL_SCHEME'],
|
||||
app_config['SERVER_HOSTNAME'],
|
||||
|
@ -95,40 +90,34 @@ class GithubOAuthConfig(OAuthConfig):
|
|||
return [org.lower() for org in allowed]
|
||||
|
||||
def get_public_url(self, suffix):
|
||||
return '%s%s' % (self._endpoint(), suffix)
|
||||
return slash_join(self._endpoint(), suffix)
|
||||
|
||||
def _endpoint(self):
|
||||
endpoint = self.config.get('GITHUB_ENDPOINT', 'https://github.com')
|
||||
if not endpoint.endswith('/'):
|
||||
endpoint = endpoint + '/'
|
||||
return endpoint
|
||||
return self.config.get('GITHUB_ENDPOINT', 'https://github.com')
|
||||
|
||||
def is_enterprise(self):
|
||||
return self._endpoint().find('.github.com') < 0
|
||||
|
||||
def authorize_endpoint(self):
|
||||
return self._get_url(self._endpoint(), '/login/oauth/authorize') + '?'
|
||||
return slash_join(self._endpoint(), '/login/oauth/authorize') + '?'
|
||||
|
||||
def token_endpoint(self):
|
||||
return self._get_url(self._endpoint(), '/login/oauth/access_token')
|
||||
return slash_join(self._endpoint(), '/login/oauth/access_token')
|
||||
|
||||
def _api_endpoint(self):
|
||||
return self.config.get('API_ENDPOINT', self._get_url(self._endpoint(), '/api/v3/'))
|
||||
return self.config.get('API_ENDPOINT', slash_join(self._endpoint(), '/api/v3/'))
|
||||
|
||||
def api_endpoint(self):
|
||||
return self._api_endpoint()[0:-1]
|
||||
|
||||
def user_endpoint(self):
|
||||
api_endpoint = self._api_endpoint()
|
||||
return self._get_url(api_endpoint, 'user')
|
||||
return slash_join(self._api_endpoint(), 'user')
|
||||
|
||||
def email_endpoint(self):
|
||||
api_endpoint = self._api_endpoint()
|
||||
return self._get_url(api_endpoint, 'user/emails')
|
||||
return slash_join(self._api_endpoint(), 'user/emails')
|
||||
|
||||
def orgs_endpoint(self):
|
||||
api_endpoint = self._api_endpoint()
|
||||
return self._get_url(api_endpoint, 'user/orgs')
|
||||
return slash_join(self._api_endpoint(), 'user/orgs')
|
||||
|
||||
def validate_client_id_and_secret(self, http_client, app_config):
|
||||
# First: Verify that the github endpoint is actually Github by checking for the
|
||||
|
@ -150,18 +139,17 @@ class GithubOAuthConfig(OAuthConfig):
|
|||
# password:
|
||||
# - If the {client_id, client_secret} pair is invalid in some way, we get a 401 error.
|
||||
# - If the pair is valid, then we get a 404 because the 'foo' token does not exists.
|
||||
validate_endpoint = self._get_url(api_endpoint, 'applications/%s/tokens/foo' % self.client_id())
|
||||
validate_endpoint = slash_join(api_endpoint, 'applications/%s/tokens/foo' % self.client_id())
|
||||
result = http_client.get(validate_endpoint, auth=(self.client_id(), self.client_secret()),
|
||||
timeout=5)
|
||||
timeout=5)
|
||||
return result.status_code == 404
|
||||
|
||||
def validate_organization(self, organization_id, http_client):
|
||||
api_endpoint = self._api_endpoint()
|
||||
org_endpoint = self._get_url(api_endpoint, 'orgs/%s' % organization_id.lower())
|
||||
org_endpoint = slash_join(self._api_endpoint(), 'orgs/%s' % organization_id.lower())
|
||||
|
||||
result = http_client.get(org_endpoint,
|
||||
headers={'Accept': 'application/vnd.github.moondragon+json'},
|
||||
timeout=5)
|
||||
headers={'Accept': 'application/vnd.github.moondragon+json'},
|
||||
timeout=5)
|
||||
|
||||
return result.status_code == 200
|
||||
|
||||
|
@ -221,19 +209,22 @@ class GitLabOAuthConfig(OAuthConfig):
|
|||
super(GitLabOAuthConfig, self).__init__(config, key_name)
|
||||
|
||||
def _endpoint(self):
|
||||
endpoint = self.config.get('GITLAB_ENDPOINT', 'https://gitlab.com')
|
||||
if not endpoint.endswith('/'):
|
||||
endpoint = endpoint + '/'
|
||||
return endpoint
|
||||
return self.config.get('GITLAB_ENDPOINT', 'https://gitlab.com')
|
||||
|
||||
def api_endpoint(self):
|
||||
return self._endpoint()
|
||||
|
||||
def get_public_url(self, suffix):
|
||||
return slash_join(self._endpoint(), suffix)
|
||||
|
||||
def service_name(self):
|
||||
return 'GitLab'
|
||||
|
||||
def authorize_endpoint(self):
|
||||
return self._get_url(self._endpoint(), '/oauth/authorize')
|
||||
return slash_join(self._endpoint(), '/oauth/authorize')
|
||||
|
||||
def token_endpoint(self):
|
||||
return self._get_url(self._endpoint(), '/oauth/token')
|
||||
return slash_join(self._endpoint(), '/oauth/token')
|
||||
|
||||
def validate_client_id_and_secret(self, http_client, app_config):
|
||||
url = self.token_endpoint()
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import re
|
||||
import string
|
||||
import anunidecode
|
||||
import re
|
||||
|
||||
|
||||
INVALID_PASSWORD_MESSAGE = 'Invalid password, password must be at least ' + \
|
||||
|
|
Reference in a new issue