Ejemplo n.º 1
0
            comment_list_response = get_github(comment_list_url, etag)

            # If we got a 304, there are no new comments, so we're done with this commit
            if comment_list_response.status_code == 304:
                continue

            # Hopefully the status code is 200 otherwise, but if not bail on this commit
            if comment_list_response.status_code != 200:
                print("ERR: Received status code %s from github for %s" %
                        (comment_list_response.status_code, comment_list_url), file=sys.stderr)
                continue

            comment_list = comment_list_response.json()

            # Iterate over the comments and look for the ones not yet emailed
            for comment in comment_list:
                if not comment_sent_coll.find_one({'comment.url': comment["url"]}):
                    # Fake a commit_comment event
                    handle_commit_comment({'comment': comment})
                    comment_sent_coll.insert({'comment': comment, 'last_sent': time.time()})

            # Insert or update the comment list record
            if record:
                record['etag'] = comment_list_response.headers['etag']
                record['comment_list'] = comment_list
                commit_comment_coll.save(record)
            else:
                commit_comment_coll.insert({'comment_list_url': comment_list_url,
                    'etag': comment_list_response.headers['etag'],
                    'comment_list': comment_list})
Ejemplo n.º 2
0
def application(environ, start_response):
    """ Entry point for mod_wsgi """

    # We always respond with text/plain no matter what, so set that
    response_headers = [('Content-Type', 'text/plain')]

    # Check that all the necessary environment variables are set
    if 'GHEH_SMTP_SERVER' not in os.environ or \
            'GHEH_EMAIL_TO' not in os.environ or \
            'GHEH_EMAIL_FROM' not in os.environ or \
            'GHEH_DB_ENVVAR' not in os.environ or \
            os.environ['GHEH_DB_ENVVAR'] not in os.environ or \
            'GHEH_DB_NAME' not in os.environ:
        print("Missing required environment variables", file=environ['wsgi.errors'])
        start_response('500 Internal Server Error', response_headers)
        return [b'Service not properly configured, please check that all mandatory environment variables are set']

    # Check that this request is the right kind of thing: a POST of type
    # application/json with a known length
    if environ['REQUEST_METHOD'] != 'POST':
        start_response('405 Method Not Allowed', response_headers)
        return [b'Only POST messages are accepted']

    if 'CONTENT_TYPE' not in environ or environ['CONTENT_TYPE'] != 'application/json':
        print("Invalid content-type %s" % environ.get('CONTENT_TYPE', None),
                file=environ['wsgi.errors'])
        start_response('415 Unsupported Media Type', response_headers)
        return [b'Requests must be of type application/json']

    try:
        content_length = int(environ['CONTENT_LENGTH'])
    except (KeyError, ValueError):
        start_response('411 Length required', response_headers)
        return [b'Invalid content length']

    # Look for the github headers
    if 'HTTP_X_GITHUB_EVENT' not in environ:
        print("Missing X-Github-Event", file=environ['wsgi.errors'])
        start_response('400 Bad Request', response_headers)
        return [b'Invalid event type']

    event_type = environ['HTTP_X_GITHUB_EVENT']

    # Read the post data
    # Errors will be automatically converted to a 500
    post_data = environ['wsgi.input'].read(content_length)

    # If a secret was set, validate the post data
    if 'GHEH_GITHUB_SECRET' in os.environ:
        if 'HTTP_X_HUB_SIGNATURE' not in environ:
            print("Missing signature", file=environ['wsgi.errors'])
            start_response('401 Unauthorized', response_headers)
            return [b'Missing signature']

        # Only sha1 is used currently
        if not environ['HTTP_X_HUB_SIGNATURE'].startswith('sha1='):
            print("Signature not sha1", file=environ['wsgi.errors'])
            start_response('401 Unauthorized', response_headers)
            return [b'Invalid signature']

        digester = hmac.new(os.environ['GHEH_GITHUB_SECRET'].encode('utf-8'),
                msg=post_data, digestmod=hashlib.sha1)
        if 'sha1=' + digester.hexdigest() != environ['HTTP_X_HUB_SIGNATURE']:
            print("Signature mismatch", file=environ['wsgi.errors'])
            start_response('401 Unauthorized', response_headers)
            return [b'Invalid signature']

    # Convert the post data to a string so we can start actually using it
    # JSON is required to be in utf-8, utf-16, or utf-32, but github only ever
    # uses utf-8, praise be, so just go ahead and assume that
    try:
        post_str = post_data.decode('utf-8')
    except UnicodeDecodeError:
        print("Unable to decode JSON", file=environ['wsgi.errors'])
        start_response('400 Bad Request', response_headers)
        return [b'Invalid data']

    # Parse the post data
    try:
        event_data = json.loads(post_str)
    except ValueError:
        print("Unable to parse JSON", file=environ['wsgi.errors'])
        start_response('400 Bad Request', response_headers)
        return [b'Invalid data']

    # Done with parsing the request, dispatch the data to the event handler
    if event_type == "pull_request":
        handle_pull_request(event_data)
    elif event_type == "issue_comment":
        handle_issue_comment(event_data)
    elif event_type == "pull_request_review_comment":
        handle_pull_request_review_comment(event_data)
    elif event_type == "commit_comment":
        handle_commit_comment(event_data)

    start_response('200 OK', response_headers)
    return [b'']