From 7fcfe05f8536a94189281b08f41d712b2421345a Mon Sep 17 00:00:00 2001 From: Filip Valder Date: Fri, 9 Dec 2016 10:55:25 +0100 Subject: [PATCH] Fix issue #251: - support for mupltiple SCM URLs (logic was broken when there were more than one SCM URL in SCMURLS conf. var) - unsplit-brain handling of SCM URLs between frontend and backend --- module_build_service/scm.py | 27 ++++++++------------------- module_build_service/utils.py | 31 +++++++++++++++++++++++++++++++ module_build_service/views.py | 5 +++-- 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/module_build_service/scm.py b/module_build_service/scm.py index 44570c29..09b8809d 100644 --- a/module_build_service/scm.py +++ b/module_build_service/scm.py @@ -45,23 +45,12 @@ class SCM(object): "SCM abstraction class" # Assuming git for HTTP schemas - types = { - "git": ("git://", "git+http://", "git+https://", - "git+rsync://", "http://", "https://", "file://") - } + types = module_build_service.utils.scm_url_schemes() def __init__(self, url, allowed_scm=None, allow_local = False): """Initialize the SCM object using the specified scmurl. If url is not in the list of allowed_scm, an error will be raised. - NOTE: only git URLs in the following formats are supported atm: - git:// - git+http:// - git+https:// - git+rsync:// - http:// - https:// - file:// :param str url: The unmodified scmurl :param list allowed_scm: The list of allowed SCMs, optional @@ -69,16 +58,15 @@ class SCM(object): """ if allowed_scm: - for allowed in allowed_scm: - if (url.startswith(allowed) - or (allow_local and url.startswith("file://"))): - break - else: - raise Unauthorized( - '%s is not in the list of allowed SCMs' % url) + if not (url.startswith(tuple(allowed_scm)) or + (allow_local and url.startswith("file://"))): + raise Unauthorized( + '%s is not in the list of allowed SCMs' % url) self.url = url + # once we have more than one SCM provider, we will need some more + # sophisticated lookup logic for scmtype, schemes in SCM.types.items(): if self.url.startswith(schemes): self.scheme = scmtype @@ -86,6 +74,7 @@ class SCM(object): else: raise ValidationError('Invalid SCM URL: %s' % url) + # git is the only one supported SCM provider atm if self.scheme == "git": match = re.search(r"^(?P.*/(?P[^?]*))(\?#(?P.*))?", url) self.repository = match.group("repository") diff --git a/module_build_service/utils.py b/module_build_service/utils.py index 023e3c59..5a14211f 100644 --- a/module_build_service/utils.py +++ b/module_build_service/utils.py @@ -494,3 +494,34 @@ def insert_fake_baseruntime(): module.state = models.BUILD_STATES['done'] module.state_reason = 'Artificially created.' db.session.commit() + + +def scm_url_schemes(terse=False): + """ + Definition of URL schemes supported by both frontend and scheduler. + + NOTE: only git URLs in the following formats are supported atm: + git:// + git+http:// + git+https:// + git+rsync:// + http:// + https:// + file:// + + :param terse=False: Whether to return terse list of unique URL schemes + even without the "://". + """ + + scm_types = { + "git": ("git://", "git+http://", "git+https://", + "git+rsync://", "http://", "https://", "file://") + } + + if not terse: + return scm_types + else: + scheme_list = [] + for scm_type, scm_schemes in scm_types.items(): + scheme_list.extend([scheme[:-3] for scheme in scm_schemes]) + return list(set(scheme_list)) diff --git a/module_build_service/views.py b/module_build_service/views.py index bd04e189..57c7af1b 100644 --- a/module_build_service/views.py +++ b/module_build_service/views.py @@ -36,7 +36,7 @@ from flask.views import MethodView from module_build_service import app, conf, log from module_build_service import models, db -from module_build_service.utils import pagination_metadata, filter_module_builds, submit_module_build +from module_build_service.utils import pagination_metadata, filter_module_builds, submit_module_build, scm_url_schemes from module_build_service.errors import ( ValidationError, Unauthorized, NotFound) @@ -115,8 +115,9 @@ class ModuleBuildAPI(MethodView): log.error("The submitted scmurl %r is not allowed" % url) raise Unauthorized("The submitted scmurl %s is not allowed" % url) + schemes_re = '|'.join(map(re.escape, scm_url_schemes(terse=True))) scmurl_re = re.compile( - r"(?P(?:(?Pgit)://(?P[^/]+))?" + r"(?P(?:(?P(" + schemes_re + r"))://(?P[^/]+))?" r"(?P/[^\?]+))\?(?P[^#]*)#(?P.+)") if not scmurl_re.match(url): log.error("The submitted scmurl %r is not valid" % url)