Merge pull request #523 from coreos-inc/bttrigger2

Add schema validation to all external trigger types
This commit is contained in:
josephschorr 2015-09-22 13:36:46 -04:00
commit 4a79311d26
3 changed files with 297 additions and 6 deletions

View file

@ -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']

View file

@ -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()

View file

@ -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()