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
|
|
|
|