Completed
Push — master ( 219e97...2114cf )
by Dieter
01:21
created

buildtimetrend.travis.process_notification_payload()   C

Complexity

Conditions 7

Size

Total Lines 48

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 7
dl 0
loc 48
rs 5.5
1
# vim: set expandtab sw=4 ts=4:
2
"""
3
Interface to Travis CI API.
4
5
Copyright (C) 2014-2015 Dieter Adriaenssens <[email protected]>
6
7
This file is part of buildtimetrend/python-lib
8
<https://github.com/buildtimetrend/python-lib/>
9
10
This program is free software: you can redistribute it and/or modify
11
it under the terms of the GNU Affero General Public License as published by
12
the Free Software Foundation, either version 3 of the License, or
13
any later version.
14
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
GNU Affero General Public License for more details.
19
20
You should have received a copy of the GNU Affero General Public License
21
along with this program. If not, see <http://www.gnu.org/licenses/>.
22
"""
23
from builtins import str
24
import json
25
from hashlib import sha256
26
from buildtimetrend import logger
27
from buildtimetrend.tools import check_num_string
28
from buildtimetrend.tools import is_string
29
from buildtimetrend.tools import get_repo_slug
30
from buildtimetrend.settings import Settings
31
32
33
def convert_build_result(result):
34
    """
35
    Convert Travis build result to a more readable value.
36
37
    Parameters:
38
    - result : numerical build result
39
    """
40
    result = check_num_string(result, "result")
41
42
    if result is 0:
43
        build_result = "passed"
44
    elif result is 1:
45
        build_result = "failed"
46
    else:
47
        build_result = "errored"
48
49
    return build_result
50
51
52
def process_notification_payload(payload):
53
    """
54
    Extract repo slug and build number from Travis notification payload.
55
56
    Returns a dictionary with "repo" and "build" information,
57
    or an empty dictionary if the payload could not be processed.
58
59
    Deprecated behaviour : Currently the repo and build information are
60
    also stored in the "settings" object,
61
    but this will be removed in the near future.
62
63
    Parameters:
64
    - payload : Travis CI notification payload
65
    """
66
    settings = Settings()
67
    parameters = {}
68
69
    if payload is None:
70
        logger.warning("Travis notification payload is not set")
71
        return parameters
72
73
    if not is_string(payload):
74
        logger.warning("Travis notification payload is incorrect :"
75
                       " string expected, got %s", type(payload))
76
        return parameters
77
78
    json_payload = json.loads(payload)
79
    logger.info("Travis Payload : %r.", json_payload)
80
81
    # get repo name from payload
82
    if ("repository" in json_payload and
83
            "owner_name" in json_payload["repository"] and
84
            "name" in json_payload["repository"]):
85
86
        repo = get_repo_slug(json_payload["repository"]["owner_name"],
87
                             json_payload["repository"]["name"])
88
89
        logger.info("Build repo : %s", repo)
90
        settings.set_project_name(repo)
91
        parameters["repo"] = repo
92
93
    # get build number from payload
94
    if "number" in json_payload:
95
        logger.info("Build number : %s", str(json_payload["number"]))
96
        settings.add_setting('build', json_payload['number'])
97
        parameters["build"] = json_payload['number']
98
99
    return parameters
100
101
102
def check_authorization(repo, auth_header):
103
    """
104
    Check if Travis CI notification has a correct Authorization header.
105
106
    This check is enabled if travis_account_token is defined in settings.
107
108
    More information on the Authorization header :
109
    http://docs.travis-ci.com/user/notifications/#Authorization-for-Webhooks
110
111
    Returns true if Authorization header is valid, but also if
112
    travis_account_token is not defined.
113
114
    Parameters:
115
    - repo : git repo name
116
    - auth_header : Travis CI notification Authorization header
117
    """
118
    # get Travis account token from Settings
119
    token = Settings().get_setting("travis_account_token")
120
121
    # return True if token is not set
122
    if token is None:
123
        logger.info("Setting travis_account_token is not defined,"
124
                    " Travis CI notification Authorization header"
125
                    " is not checked.")
126
        return True
127
128
    # check if parameters are strings
129
    if is_string(repo) and is_string(auth_header) and is_string(token):
130
        # generate hash (encode string to bytes first)
131
        auth_hash = sha256((repo + token).encode('utf-8')).hexdigest()
132
133
        # compare hash with Authorization header
134
        if auth_hash == auth_header:
135
            logger.info("Travis CI notification Authorization header"
136
                        " is correct.")
137
            return True
138
        else:
139
            logger.error("Travis CI notification Authorization header"
140
                         " is incorrect.")
141
            return False
142
    else:
143
        logger.debug("repo, auth_header and travis_auth_token"
144
                     " should be strings.")
145
        return False
146