Merge pull request #523 from coreos-inc/bttrigger2
Add schema validation to all external trigger types
This commit is contained in:
commit
4a79311d26
3 changed files with 297 additions and 6 deletions
|
@ -1,8 +1,10 @@
|
|||
import logging
|
||||
import re
|
||||
|
||||
from jsonschema import validate
|
||||
from buildtrigger.triggerutil import (RepositoryReadException, TriggerActivationException,
|
||||
TriggerDeactivationException, TriggerStartException,
|
||||
InvalidPayloadException,
|
||||
determine_build_ref, raise_if_skipped_build,
|
||||
find_matching_branches)
|
||||
|
||||
|
@ -18,11 +20,172 @@ logger = logging.getLogger(__name__)
|
|||
_BITBUCKET_COMMIT_URL = 'https://bitbucket.org/%s/commits/%s'
|
||||
_RAW_AUTHOR_REGEX = re.compile(r'.*<(.+)>')
|
||||
|
||||
BITBUCKET_WEBHOOK_PAYLOAD_SCHEMA = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'repository': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'full_name': {
|
||||
'type': 'string',
|
||||
},
|
||||
},
|
||||
'required': ['full_name'],
|
||||
},
|
||||
'push': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'changes': {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'new': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'target': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'hash': {
|
||||
'type': 'string'
|
||||
},
|
||||
'message': {
|
||||
'type': 'string'
|
||||
},
|
||||
'date': {
|
||||
'type': 'string'
|
||||
},
|
||||
'author': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'user': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'username': {
|
||||
'type': 'string',
|
||||
},
|
||||
'links': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'html': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'href': {
|
||||
'type': 'string',
|
||||
},
|
||||
},
|
||||
'required': ['href'],
|
||||
},
|
||||
'avatar': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'href': {
|
||||
'type': 'string',
|
||||
},
|
||||
},
|
||||
'required': ['href'],
|
||||
},
|
||||
},
|
||||
'required': ['html', 'avatar'],
|
||||
},
|
||||
},
|
||||
'required': ['username'],
|
||||
},
|
||||
},
|
||||
'required': ['user'],
|
||||
},
|
||||
'links': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'html': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'href': {
|
||||
'type': 'string',
|
||||
},
|
||||
},
|
||||
'required': ['href'],
|
||||
},
|
||||
},
|
||||
'required': ['html'],
|
||||
},
|
||||
},
|
||||
'required': ['hash', 'message', 'date'],
|
||||
},
|
||||
},
|
||||
'required': ['target'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'required': ['changes'],
|
||||
},
|
||||
},
|
||||
'actor': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'username': {
|
||||
'type': 'string',
|
||||
},
|
||||
'links': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'html': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'href': {
|
||||
'type': 'string',
|
||||
},
|
||||
},
|
||||
'required': ['href'],
|
||||
},
|
||||
'avatar': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'href': {
|
||||
'type': 'string',
|
||||
},
|
||||
},
|
||||
'required': ['href'],
|
||||
},
|
||||
},
|
||||
'required': ['html', 'avatar'],
|
||||
},
|
||||
},
|
||||
'required': ['username'],
|
||||
},
|
||||
'required': ['push', 'repository'],
|
||||
}
|
||||
|
||||
BITBUCKET_COMMIT_INFO_SCHEMA = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'node': {
|
||||
'type': 'string',
|
||||
},
|
||||
'message': {
|
||||
'type': 'string',
|
||||
},
|
||||
'timestamp': {
|
||||
'type': 'string',
|
||||
},
|
||||
'raw_author': {
|
||||
'type': 'string',
|
||||
},
|
||||
},
|
||||
'required': ['node', 'message', 'timestamp']
|
||||
}
|
||||
|
||||
def get_transformed_commit_info(bb_commit, ref, default_branch, repository_name, lookup_author):
|
||||
""" Returns the BitBucket commit information transformed into our own
|
||||
payload format.
|
||||
"""
|
||||
# TODO(jschorr): Validate commit JSON
|
||||
try:
|
||||
validate(bb_commit, BITBUCKET_COMMIT_INFO_SCHEMA)
|
||||
except Exception as exc:
|
||||
raise InvalidPayloadException(exc.message)
|
||||
|
||||
commit = JSONPathDict(bb_commit)
|
||||
|
||||
config = SafeDictSetter()
|
||||
|
@ -51,7 +214,10 @@ def get_transformed_webhook_payload(bb_payload, default_branch=None):
|
|||
""" Returns the BitBucket webhook JSON payload transformed into our own payload
|
||||
format. If the bb_payload is not valid, returns None.
|
||||
"""
|
||||
# TODO(jschorr): Validate payload JSON
|
||||
try:
|
||||
validate(bb_payload, BITBUCKET_WEBHOOK_PAYLOAD_SCHEMA)
|
||||
except Exception as exc:
|
||||
raise InvalidPayloadException(exc.message)
|
||||
|
||||
payload = JSONPathDict(bb_payload)
|
||||
change = payload['push.changes[-1].new']
|
||||
|
|
|
@ -3,11 +3,12 @@ import os.path
|
|||
import base64
|
||||
|
||||
from app import app, github_trigger
|
||||
from jsonschema import validate
|
||||
|
||||
from buildtrigger.triggerutil import (RepositoryReadException, TriggerActivationException,
|
||||
TriggerDeactivationException, TriggerStartException,
|
||||
EmptyRepositoryException, ValidationRequestException,
|
||||
SkipRequestException,
|
||||
SkipRequestException, InvalidPayloadException,
|
||||
determine_build_ref, raise_if_skipped_build,
|
||||
find_matching_branches)
|
||||
|
||||
|
@ -21,12 +22,82 @@ from github import (Github, UnknownObjectException, GithubException,
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
GITHUB_WEBHOOK_PAYLOAD_SCHEMA = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'ref': {
|
||||
'type': 'string',
|
||||
},
|
||||
'head_commit': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'id': {
|
||||
'type': 'string',
|
||||
},
|
||||
'url': {
|
||||
'type': 'string',
|
||||
},
|
||||
'message': {
|
||||
'type': 'string',
|
||||
},
|
||||
'timestamp': {
|
||||
'type': 'string',
|
||||
},
|
||||
'author': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'username': {
|
||||
'type': 'string'
|
||||
},
|
||||
'html_url': {
|
||||
'type': 'string'
|
||||
},
|
||||
'avatar_url': {
|
||||
'type': 'string'
|
||||
},
|
||||
},
|
||||
'required': ['username'],
|
||||
},
|
||||
'committer': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'username': {
|
||||
'type': 'string'
|
||||
},
|
||||
'html_url': {
|
||||
'type': 'string'
|
||||
},
|
||||
'avatar_url': {
|
||||
'type': 'string'
|
||||
},
|
||||
},
|
||||
'required': ['username'],
|
||||
},
|
||||
},
|
||||
'required': ['id', 'url', 'message', 'timestamp'],
|
||||
},
|
||||
'repository': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'ssh_url': {
|
||||
'type': 'string',
|
||||
},
|
||||
},
|
||||
'required': ['ssh_url'],
|
||||
},
|
||||
},
|
||||
'required': ['ref', 'head_commit', 'repository'],
|
||||
}
|
||||
|
||||
def get_transformed_webhook_payload(gh_payload, default_branch=None, lookup_user=None):
|
||||
""" Returns the GitHub webhook JSON payload transformed into our own payload
|
||||
format. If the gh_payload is not valid, returns None.
|
||||
"""
|
||||
# TODO(jschorr): Validate payload JSON
|
||||
try:
|
||||
validate(gh_payload, GITHUB_WEBHOOK_PAYLOAD_SCHEMA)
|
||||
except Exception as exc:
|
||||
raise InvalidPayloadException(exc.message)
|
||||
|
||||
payload = JSONPathDict(gh_payload)
|
||||
|
||||
config = SafeDictSetter()
|
||||
|
|
|
@ -2,10 +2,11 @@ import logging
|
|||
|
||||
from app import app
|
||||
|
||||
from jsonschema import validate
|
||||
from buildtrigger.triggerutil import (RepositoryReadException, TriggerActivationException,
|
||||
TriggerDeactivationException, TriggerStartException,
|
||||
EmptyRepositoryException, ValidationRequestException,
|
||||
SkipRequestException,
|
||||
SkipRequestException, InvalidPayloadException,
|
||||
determine_build_ref, raise_if_skipped_build,
|
||||
find_matching_branches)
|
||||
|
||||
|
@ -18,12 +19,65 @@ import gitlab
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
GITLAB_WEBHOOK_PAYLOAD_SCHEMA = {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'ref': {
|
||||
'type': 'string',
|
||||
},
|
||||
'checkout_sha': {
|
||||
'type': 'string',
|
||||
},
|
||||
'repository': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'git_ssh_url': {
|
||||
'type': 'string',
|
||||
},
|
||||
},
|
||||
'required': ['git_ssh_url'],
|
||||
},
|
||||
'commits': {
|
||||
'type': 'array',
|
||||
'items': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'url': {
|
||||
'type': 'string',
|
||||
},
|
||||
'message': {
|
||||
'type': 'string',
|
||||
},
|
||||
'timestamp': {
|
||||
'type': 'string',
|
||||
},
|
||||
'author': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'email': {
|
||||
'type': 'string',
|
||||
},
|
||||
},
|
||||
'required': ['email'],
|
||||
},
|
||||
},
|
||||
'required': ['url', 'message', 'timestamp'],
|
||||
},
|
||||
'minItems': 1,
|
||||
}
|
||||
},
|
||||
'required': ['ref', 'checkout_sha', 'repository'],
|
||||
}
|
||||
|
||||
def get_transformed_webhook_payload(gl_payload, default_branch=None, lookup_user=None):
|
||||
""" Returns the Gitlab webhook JSON payload transformed into our own payload
|
||||
format. If the gl_payload is not valid, returns None.
|
||||
"""
|
||||
# TODO(jschorr): Validate payload JSON
|
||||
try:
|
||||
validate(gl_payload, GITLAB_WEBHOOK_PAYLOAD_SCHEMA)
|
||||
except Exception as exc:
|
||||
raise InvalidPayloadException(exc.message)
|
||||
|
||||
payload = JSONPathDict(gl_payload)
|
||||
|
||||
config = SafeDictSetter()
|
||||
|
|
Reference in a new issue