Show More
@@ -23,17 +23,27 b' import string' | |||||
23 | import collections |
|
23 | import collections | |
24 | import logging |
|
24 | import logging | |
25 | import requests |
|
25 | import requests | |
|
26 | import urllib | |||
26 | from requests.adapters import HTTPAdapter |
|
27 | from requests.adapters import HTTPAdapter | |
27 | from requests.packages.urllib3.util.retry import Retry |
|
28 | from requests.packages.urllib3.util.retry import Retry | |
28 |
|
29 | |||
29 | from mako import exceptions |
|
30 | from mako import exceptions | |
30 |
|
31 | |||
|
32 | from rhodecode.lib.utils2 import safe_str | |||
31 | from rhodecode.translation import _ |
|
33 | from rhodecode.translation import _ | |
32 |
|
34 | |||
33 |
|
35 | |||
34 | log = logging.getLogger(__name__) |
|
36 | log = logging.getLogger(__name__) | |
35 |
|
37 | |||
36 |
|
38 | |||
|
39 | class UrlTmpl(string.Template): | |||
|
40 | ||||
|
41 | def safe_substitute(self, **kws): | |||
|
42 | # url encode the kw for usage in url | |||
|
43 | kws = {k: urllib.quote(safe_str(v)) for k, v in kws.items()} | |||
|
44 | return super(UrlTmpl, self).safe_substitute(**kws) | |||
|
45 | ||||
|
46 | ||||
37 | class IntegrationTypeBase(object): |
|
47 | class IntegrationTypeBase(object): | |
38 | """ Base class for IntegrationType plugins """ |
|
48 | """ Base class for IntegrationType plugins """ | |
39 | is_dummy = False |
|
49 | is_dummy = False | |
@@ -217,7 +227,9 b' class WebhookDataHandler(CommitParsingDa' | |||||
217 | common_vars.update(extra_vars) |
|
227 | common_vars.update(extra_vars) | |
218 |
|
228 | |||
219 | template_url = self.template_url.replace('${extra:', '${extra__') |
|
229 | template_url = self.template_url.replace('${extra:', '${extra__') | |
220 | return string.Template(template_url).safe_substitute(**common_vars) |
|
230 | for k, v in common_vars.items(): | |
|
231 | template_url = UrlTmpl(template_url).safe_substitute(**{k: v}) | |||
|
232 | return template_url | |||
221 |
|
233 | |||
222 | def repo_push_event_handler(self, event, data): |
|
234 | def repo_push_event_handler(self, event, data): | |
223 | url = self.get_base_parsed_template(data) |
|
235 | url = self.get_base_parsed_template(data) | |
@@ -228,20 +240,18 b' class WebhookDataHandler(CommitParsingDa' | |||||
228 | if '${branch}' in url or '${branch_head}' in url or '${commit_id}' in url: |
|
240 | if '${branch}' in url or '${branch_head}' in url or '${commit_id}' in url: | |
229 | # call it multiple times, for each branch if used in variables |
|
241 | # call it multiple times, for each branch if used in variables | |
230 | for branch, commit_ids in branches_commits.items(): |
|
242 | for branch, commit_ids in branches_commits.items(): | |
231 |
branch_url = |
|
243 | branch_url = UrlTmpl(url).safe_substitute(branch=branch) | |
232 |
|
244 | |||
233 | if '${branch_head}' in branch_url: |
|
245 | if '${branch_head}' in branch_url: | |
234 | # last commit in the aggregate is the head of the branch |
|
246 | # last commit in the aggregate is the head of the branch | |
235 | branch_head = commit_ids['branch_head'] |
|
247 | branch_head = commit_ids['branch_head'] | |
236 |
branch_url = |
|
248 | branch_url = UrlTmpl(branch_url).safe_substitute(branch_head=branch_head) | |
237 | branch_head=branch_head) |
|
|||
238 |
|
249 | |||
239 | # call further down for each commit if used |
|
250 | # call further down for each commit if used | |
240 | if '${commit_id}' in branch_url: |
|
251 | if '${commit_id}' in branch_url: | |
241 | for commit_data in commit_ids['commits']: |
|
252 | for commit_data in commit_ids['commits']: | |
242 | commit_id = commit_data['raw_id'] |
|
253 | commit_id = commit_data['raw_id'] | |
243 |
commit_url = |
|
254 | commit_url = UrlTmpl(branch_url).safe_substitute(commit_id=commit_id) | |
244 | commit_id=commit_id) |
|
|||
245 | # register per-commit call |
|
255 | # register per-commit call | |
246 | log.debug( |
|
256 | log.debug( | |
247 | 'register %s call(%s) to url %s', |
|
257 | 'register %s call(%s) to url %s', | |
@@ -251,36 +261,34 b' class WebhookDataHandler(CommitParsingDa' | |||||
251 |
|
261 | |||
252 | else: |
|
262 | else: | |
253 | # register per-branch call |
|
263 | # register per-branch call | |
254 | log.debug( |
|
264 | log.debug('register %s call(%s) to url %s', | |
255 | 'register %s call(%s) to url %s', |
|
|||
256 | self.name, event, branch_url) |
|
265 | self.name, event, branch_url) | |
257 | url_calls.append( |
|
266 | url_calls.append((branch_url, self.headers, data)) | |
258 | (branch_url, self.headers, data)) |
|
|||
259 |
|
267 | |||
260 | else: |
|
268 | else: | |
261 | log.debug( |
|
269 | log.debug('register %s call(%s) to url %s', self.name, event, url) | |
262 | 'register %s call(%s) to url %s', self.name, event, url) |
|
|||
263 | url_calls.append((url, self.headers, data)) |
|
270 | url_calls.append((url, self.headers, data)) | |
264 |
|
271 | |||
265 | return url_calls |
|
272 | return url_calls | |
266 |
|
273 | |||
267 | def repo_create_event_handler(self, event, data): |
|
274 | def repo_create_event_handler(self, event, data): | |
268 | url = self.get_base_parsed_template(data) |
|
275 | url = self.get_base_parsed_template(data) | |
269 | log.debug( |
|
276 | log.debug('register %s call(%s) to url %s', self.name, event, url) | |
270 | 'register %s call(%s) to url %s', self.name, event, url) |
|
|||
271 | return [(url, self.headers, data)] |
|
277 | return [(url, self.headers, data)] | |
272 |
|
278 | |||
273 | def pull_request_event_handler(self, event, data): |
|
279 | def pull_request_event_handler(self, event, data): | |
274 | url = self.get_base_parsed_template(data) |
|
280 | url = self.get_base_parsed_template(data) | |
275 | log.debug( |
|
281 | log.debug('register %s call(%s) to url %s', self.name, event, url) | |
276 | 'register %s call(%s) to url %s', self.name, event, url) |
|
282 | pr_vars = [ | |
277 | url = string.Template(url).safe_substitute( |
|
283 | ('pull_request_id', data['pullrequest']['pull_request_id']), | |
278 |
pull_request_ |
|
284 | ('pull_request_title', data['pullrequest']['title']), | |
279 |
pull_request_ |
|
285 | ('pull_request_url', data['pullrequest']['url']), | |
280 |
pull_request_ |
|
286 | ('pull_request_shadow_url', data['pullrequest']['shadow_url']), | |
281 |
pull_request_ |
|
287 | ('pull_request_commits_uid', data['pullrequest']['commits_uid']), | |
282 | pull_request_commits_uid=data['pullrequest']['commits_uid'], |
|
288 | ] | |
283 | ) |
|
289 | for k, v in pr_vars: | |
|
290 | url = UrlTmpl(url).safe_substitute(**{k: v}) | |||
|
291 | ||||
284 | return [(url, self.headers, data)] |
|
292 | return [(url, self.headers, data)] | |
285 |
|
293 | |||
286 | def __call__(self, event, data): |
|
294 | def __call__(self, event, data): |
@@ -188,7 +188,7 b' class WebhookIntegrationType(Integration' | |||||
188 | handler = WebhookDataHandler(template_url, headers) |
|
188 | handler = WebhookDataHandler(template_url, headers) | |
189 |
|
189 | |||
190 | url_calls = handler(event, data) |
|
190 | url_calls = handler(event, data) | |
191 |
log.debug(' |
|
191 | log.debug('Webhook: calling following urls: %s', [x[0] for x in url_calls]) | |
192 |
|
192 | |||
193 | run_task(post_to_webhook, url_calls, self.settings) |
|
193 | run_task(post_to_webhook, url_calls, self.settings) | |
194 |
|
194 |
@@ -78,15 +78,18 b' def test_webook_parse_url_for_create_eve' | |||||
78 | ('http://server.com/${repo_name}/${pull_request_id}', |
|
78 | ('http://server.com/${repo_name}/${pull_request_id}', | |
79 | ['http://server.com/foo/999']), |
|
79 | ['http://server.com/foo/999']), | |
80 | ('http://server.com/${repo_name}/${pull_request_url}', |
|
80 | ('http://server.com/${repo_name}/${pull_request_url}', | |
81 |
['http://server.com/foo/http |
|
81 | ['http://server.com/foo/http%3A//pr-url.com']), | |
|
82 | ('http://server.com/${repo_name}/${pull_request_url}/?TITLE=${pull_request_title}', | |||
|
83 | ['http://server.com/foo/http%3A//pr-url.com/?TITLE=example-pr-title%20Ticket%20%23123']), | |||
|
84 | ('http://server.com/${repo_name}/?SHADOW_URL=${pull_request_shadow_url}', | |||
|
85 | ['http://server.com/foo/?SHADOW_URL=http%3A//pr-url.com/repository']), | |||
82 | ]) |
|
86 | ]) | |
83 | def test_webook_parse_url_for_pull_request_event( |
|
87 | def test_webook_parse_url_for_pull_request_event(base_data, template, expected_urls): | |
84 | base_data, template, expected_urls): |
|
|||
85 |
|
88 | |||
86 | base_data['pullrequest'] = { |
|
89 | base_data['pullrequest'] = { | |
87 | 'pull_request_id': 999, |
|
90 | 'pull_request_id': 999, | |
88 | 'url': 'http://pr-url.com', |
|
91 | 'url': 'http://pr-url.com', | |
89 | 'title': 'example-pr-title', |
|
92 | 'title': 'example-pr-title Ticket #123', | |
90 | 'commits_uid': 'abcdefg1234', |
|
93 | 'commits_uid': 'abcdefg1234', | |
91 | 'shadow_url': 'http://pr-url.com/repository' |
|
94 | 'shadow_url': 'http://pr-url.com/repository' | |
92 | } |
|
95 | } |
General Comments 0
You need to be logged in to leave comments.
Login now