##// END OF EJS Templates
hooks: fixed again unicode problems with new pull-request link generator
marcink -
r3503:0a6f9ae0 stable
parent child Browse files
Show More
@@ -1,492 +1,492 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2013-2019 RhodeCode GmbH
3 # Copyright (C) 2013-2019 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 """
22 """
23 Set of hooks run by RhodeCode Enterprise
23 Set of hooks run by RhodeCode Enterprise
24 """
24 """
25
25
26 import os
26 import os
27 import collections
27 import collections
28 import logging
28 import logging
29
29
30 import rhodecode
30 import rhodecode
31 from rhodecode import events
31 from rhodecode import events
32 from rhodecode.lib import helpers as h
32 from rhodecode.lib import helpers as h
33 from rhodecode.lib import audit_logger
33 from rhodecode.lib import audit_logger
34 from rhodecode.lib.utils2 import safe_str
34 from rhodecode.lib.utils2 import safe_str
35 from rhodecode.lib.exceptions import (
35 from rhodecode.lib.exceptions import (
36 HTTPLockedRC, HTTPBranchProtected, UserCreationError)
36 HTTPLockedRC, HTTPBranchProtected, UserCreationError)
37 from rhodecode.model.db import Repository, User
37 from rhodecode.model.db import Repository, User
38
38
39 log = logging.getLogger(__name__)
39 log = logging.getLogger(__name__)
40
40
41
41
42 class HookResponse(object):
42 class HookResponse(object):
43 def __init__(self, status, output):
43 def __init__(self, status, output):
44 self.status = status
44 self.status = status
45 self.output = output
45 self.output = output
46
46
47 def __add__(self, other):
47 def __add__(self, other):
48 other_status = getattr(other, 'status', 0)
48 other_status = getattr(other, 'status', 0)
49 new_status = max(self.status, other_status)
49 new_status = max(self.status, other_status)
50 other_output = getattr(other, 'output', '')
50 other_output = getattr(other, 'output', '')
51 new_output = self.output + other_output
51 new_output = self.output + other_output
52
52
53 return HookResponse(new_status, new_output)
53 return HookResponse(new_status, new_output)
54
54
55 def __bool__(self):
55 def __bool__(self):
56 return self.status == 0
56 return self.status == 0
57
57
58
58
59 def is_shadow_repo(extras):
59 def is_shadow_repo(extras):
60 """
60 """
61 Returns ``True`` if this is an action executed against a shadow repository.
61 Returns ``True`` if this is an action executed against a shadow repository.
62 """
62 """
63 return extras['is_shadow_repo']
63 return extras['is_shadow_repo']
64
64
65
65
66 def _get_scm_size(alias, root_path):
66 def _get_scm_size(alias, root_path):
67
67
68 if not alias.startswith('.'):
68 if not alias.startswith('.'):
69 alias += '.'
69 alias += '.'
70
70
71 size_scm, size_root = 0, 0
71 size_scm, size_root = 0, 0
72 for path, unused_dirs, files in os.walk(safe_str(root_path)):
72 for path, unused_dirs, files in os.walk(safe_str(root_path)):
73 if path.find(alias) != -1:
73 if path.find(alias) != -1:
74 for f in files:
74 for f in files:
75 try:
75 try:
76 size_scm += os.path.getsize(os.path.join(path, f))
76 size_scm += os.path.getsize(os.path.join(path, f))
77 except OSError:
77 except OSError:
78 pass
78 pass
79 else:
79 else:
80 for f in files:
80 for f in files:
81 try:
81 try:
82 size_root += os.path.getsize(os.path.join(path, f))
82 size_root += os.path.getsize(os.path.join(path, f))
83 except OSError:
83 except OSError:
84 pass
84 pass
85
85
86 size_scm_f = h.format_byte_size_binary(size_scm)
86 size_scm_f = h.format_byte_size_binary(size_scm)
87 size_root_f = h.format_byte_size_binary(size_root)
87 size_root_f = h.format_byte_size_binary(size_root)
88 size_total_f = h.format_byte_size_binary(size_root + size_scm)
88 size_total_f = h.format_byte_size_binary(size_root + size_scm)
89
89
90 return size_scm_f, size_root_f, size_total_f
90 return size_scm_f, size_root_f, size_total_f
91
91
92
92
93 # actual hooks called by Mercurial internally, and GIT by our Python Hooks
93 # actual hooks called by Mercurial internally, and GIT by our Python Hooks
94 def repo_size(extras):
94 def repo_size(extras):
95 """Present size of repository after push."""
95 """Present size of repository after push."""
96 repo = Repository.get_by_repo_name(extras.repository)
96 repo = Repository.get_by_repo_name(extras.repository)
97 vcs_part = safe_str(u'.%s' % repo.repo_type)
97 vcs_part = safe_str(u'.%s' % repo.repo_type)
98 size_vcs, size_root, size_total = _get_scm_size(vcs_part,
98 size_vcs, size_root, size_total = _get_scm_size(vcs_part,
99 repo.repo_full_path)
99 repo.repo_full_path)
100 msg = ('Repository `%s` size summary %s:%s repo:%s total:%s\n'
100 msg = ('Repository `%s` size summary %s:%s repo:%s total:%s\n'
101 % (repo.repo_name, vcs_part, size_vcs, size_root, size_total))
101 % (repo.repo_name, vcs_part, size_vcs, size_root, size_total))
102 return HookResponse(0, msg)
102 return HookResponse(0, msg)
103
103
104
104
105 def pre_push(extras):
105 def pre_push(extras):
106 """
106 """
107 Hook executed before pushing code.
107 Hook executed before pushing code.
108
108
109 It bans pushing when the repository is locked.
109 It bans pushing when the repository is locked.
110 """
110 """
111
111
112 user = User.get_by_username(extras.username)
112 user = User.get_by_username(extras.username)
113 output = ''
113 output = ''
114 if extras.locked_by[0] and user.user_id != int(extras.locked_by[0]):
114 if extras.locked_by[0] and user.user_id != int(extras.locked_by[0]):
115 locked_by = User.get(extras.locked_by[0]).username
115 locked_by = User.get(extras.locked_by[0]).username
116 reason = extras.locked_by[2]
116 reason = extras.locked_by[2]
117 # this exception is interpreted in git/hg middlewares and based
117 # this exception is interpreted in git/hg middlewares and based
118 # on that proper return code is server to client
118 # on that proper return code is server to client
119 _http_ret = HTTPLockedRC(
119 _http_ret = HTTPLockedRC(
120 _locked_by_explanation(extras.repository, locked_by, reason))
120 _locked_by_explanation(extras.repository, locked_by, reason))
121 if str(_http_ret.code).startswith('2'):
121 if str(_http_ret.code).startswith('2'):
122 # 2xx Codes don't raise exceptions
122 # 2xx Codes don't raise exceptions
123 output = _http_ret.title
123 output = _http_ret.title
124 else:
124 else:
125 raise _http_ret
125 raise _http_ret
126
126
127 hook_response = ''
127 hook_response = ''
128 if not is_shadow_repo(extras):
128 if not is_shadow_repo(extras):
129 if extras.commit_ids and extras.check_branch_perms:
129 if extras.commit_ids and extras.check_branch_perms:
130
130
131 auth_user = user.AuthUser()
131 auth_user = user.AuthUser()
132 repo = Repository.get_by_repo_name(extras.repository)
132 repo = Repository.get_by_repo_name(extras.repository)
133 affected_branches = []
133 affected_branches = []
134 if repo.repo_type == 'hg':
134 if repo.repo_type == 'hg':
135 for entry in extras.commit_ids:
135 for entry in extras.commit_ids:
136 if entry['type'] == 'branch':
136 if entry['type'] == 'branch':
137 is_forced = bool(entry['multiple_heads'])
137 is_forced = bool(entry['multiple_heads'])
138 affected_branches.append([entry['name'], is_forced])
138 affected_branches.append([entry['name'], is_forced])
139 elif repo.repo_type == 'git':
139 elif repo.repo_type == 'git':
140 for entry in extras.commit_ids:
140 for entry in extras.commit_ids:
141 if entry['type'] == 'heads':
141 if entry['type'] == 'heads':
142 is_forced = bool(entry['pruned_sha'])
142 is_forced = bool(entry['pruned_sha'])
143 affected_branches.append([entry['name'], is_forced])
143 affected_branches.append([entry['name'], is_forced])
144
144
145 for branch_name, is_forced in affected_branches:
145 for branch_name, is_forced in affected_branches:
146
146
147 rule, branch_perm = auth_user.get_rule_and_branch_permission(
147 rule, branch_perm = auth_user.get_rule_and_branch_permission(
148 extras.repository, branch_name)
148 extras.repository, branch_name)
149 if not branch_perm:
149 if not branch_perm:
150 # no branch permission found for this branch, just keep checking
150 # no branch permission found for this branch, just keep checking
151 continue
151 continue
152
152
153 if branch_perm == 'branch.push_force':
153 if branch_perm == 'branch.push_force':
154 continue
154 continue
155 elif branch_perm == 'branch.push' and is_forced is False:
155 elif branch_perm == 'branch.push' and is_forced is False:
156 continue
156 continue
157 elif branch_perm == 'branch.push' and is_forced is True:
157 elif branch_perm == 'branch.push' and is_forced is True:
158 halt_message = 'Branch `{}` changes rejected by rule {}. ' \
158 halt_message = 'Branch `{}` changes rejected by rule {}. ' \
159 'FORCE PUSH FORBIDDEN.'.format(branch_name, rule)
159 'FORCE PUSH FORBIDDEN.'.format(branch_name, rule)
160 else:
160 else:
161 halt_message = 'Branch `{}` changes rejected by rule {}.'.format(
161 halt_message = 'Branch `{}` changes rejected by rule {}.'.format(
162 branch_name, rule)
162 branch_name, rule)
163
163
164 if halt_message:
164 if halt_message:
165 _http_ret = HTTPBranchProtected(halt_message)
165 _http_ret = HTTPBranchProtected(halt_message)
166 raise _http_ret
166 raise _http_ret
167
167
168 # Propagate to external components. This is done after checking the
168 # Propagate to external components. This is done after checking the
169 # lock, for consistent behavior.
169 # lock, for consistent behavior.
170 hook_response = pre_push_extension(
170 hook_response = pre_push_extension(
171 repo_store_path=Repository.base_path(), **extras)
171 repo_store_path=Repository.base_path(), **extras)
172 events.trigger(events.RepoPrePushEvent(
172 events.trigger(events.RepoPrePushEvent(
173 repo_name=extras.repository, extras=extras))
173 repo_name=extras.repository, extras=extras))
174
174
175 return HookResponse(0, output) + hook_response
175 return HookResponse(0, output) + hook_response
176
176
177
177
178 def pre_pull(extras):
178 def pre_pull(extras):
179 """
179 """
180 Hook executed before pulling the code.
180 Hook executed before pulling the code.
181
181
182 It bans pulling when the repository is locked.
182 It bans pulling when the repository is locked.
183 """
183 """
184
184
185 output = ''
185 output = ''
186 if extras.locked_by[0]:
186 if extras.locked_by[0]:
187 locked_by = User.get(extras.locked_by[0]).username
187 locked_by = User.get(extras.locked_by[0]).username
188 reason = extras.locked_by[2]
188 reason = extras.locked_by[2]
189 # this exception is interpreted in git/hg middlewares and based
189 # this exception is interpreted in git/hg middlewares and based
190 # on that proper return code is server to client
190 # on that proper return code is server to client
191 _http_ret = HTTPLockedRC(
191 _http_ret = HTTPLockedRC(
192 _locked_by_explanation(extras.repository, locked_by, reason))
192 _locked_by_explanation(extras.repository, locked_by, reason))
193 if str(_http_ret.code).startswith('2'):
193 if str(_http_ret.code).startswith('2'):
194 # 2xx Codes don't raise exceptions
194 # 2xx Codes don't raise exceptions
195 output = _http_ret.title
195 output = _http_ret.title
196 else:
196 else:
197 raise _http_ret
197 raise _http_ret
198
198
199 # Propagate to external components. This is done after checking the
199 # Propagate to external components. This is done after checking the
200 # lock, for consistent behavior.
200 # lock, for consistent behavior.
201 hook_response = ''
201 hook_response = ''
202 if not is_shadow_repo(extras):
202 if not is_shadow_repo(extras):
203 extras.hook_type = extras.hook_type or 'pre_pull'
203 extras.hook_type = extras.hook_type or 'pre_pull'
204 hook_response = pre_pull_extension(
204 hook_response = pre_pull_extension(
205 repo_store_path=Repository.base_path(), **extras)
205 repo_store_path=Repository.base_path(), **extras)
206 events.trigger(events.RepoPrePullEvent(
206 events.trigger(events.RepoPrePullEvent(
207 repo_name=extras.repository, extras=extras))
207 repo_name=extras.repository, extras=extras))
208
208
209 return HookResponse(0, output) + hook_response
209 return HookResponse(0, output) + hook_response
210
210
211
211
212 def post_pull(extras):
212 def post_pull(extras):
213 """Hook executed after client pulls the code."""
213 """Hook executed after client pulls the code."""
214
214
215 audit_user = audit_logger.UserWrap(
215 audit_user = audit_logger.UserWrap(
216 username=extras.username,
216 username=extras.username,
217 ip_addr=extras.ip)
217 ip_addr=extras.ip)
218 repo = audit_logger.RepoWrap(repo_name=extras.repository)
218 repo = audit_logger.RepoWrap(repo_name=extras.repository)
219 audit_logger.store(
219 audit_logger.store(
220 'user.pull', action_data={'user_agent': extras.user_agent},
220 'user.pull', action_data={'user_agent': extras.user_agent},
221 user=audit_user, repo=repo, commit=True)
221 user=audit_user, repo=repo, commit=True)
222
222
223 output = ''
223 output = ''
224 # make lock is a tri state False, True, None. We only make lock on True
224 # make lock is a tri state False, True, None. We only make lock on True
225 if extras.make_lock is True and not is_shadow_repo(extras):
225 if extras.make_lock is True and not is_shadow_repo(extras):
226 user = User.get_by_username(extras.username)
226 user = User.get_by_username(extras.username)
227 Repository.lock(Repository.get_by_repo_name(extras.repository),
227 Repository.lock(Repository.get_by_repo_name(extras.repository),
228 user.user_id,
228 user.user_id,
229 lock_reason=Repository.LOCK_PULL)
229 lock_reason=Repository.LOCK_PULL)
230 msg = 'Made lock on repo `%s`' % (extras.repository,)
230 msg = 'Made lock on repo `%s`' % (extras.repository,)
231 output += msg
231 output += msg
232
232
233 if extras.locked_by[0]:
233 if extras.locked_by[0]:
234 locked_by = User.get(extras.locked_by[0]).username
234 locked_by = User.get(extras.locked_by[0]).username
235 reason = extras.locked_by[2]
235 reason = extras.locked_by[2]
236 _http_ret = HTTPLockedRC(
236 _http_ret = HTTPLockedRC(
237 _locked_by_explanation(extras.repository, locked_by, reason))
237 _locked_by_explanation(extras.repository, locked_by, reason))
238 if str(_http_ret.code).startswith('2'):
238 if str(_http_ret.code).startswith('2'):
239 # 2xx Codes don't raise exceptions
239 # 2xx Codes don't raise exceptions
240 output += _http_ret.title
240 output += _http_ret.title
241
241
242 # Propagate to external components.
242 # Propagate to external components.
243 hook_response = ''
243 hook_response = ''
244 if not is_shadow_repo(extras):
244 if not is_shadow_repo(extras):
245 extras.hook_type = extras.hook_type or 'post_pull'
245 extras.hook_type = extras.hook_type or 'post_pull'
246 hook_response = post_pull_extension(
246 hook_response = post_pull_extension(
247 repo_store_path=Repository.base_path(), **extras)
247 repo_store_path=Repository.base_path(), **extras)
248 events.trigger(events.RepoPullEvent(
248 events.trigger(events.RepoPullEvent(
249 repo_name=extras.repository, extras=extras))
249 repo_name=extras.repository, extras=extras))
250
250
251 return HookResponse(0, output) + hook_response
251 return HookResponse(0, output) + hook_response
252
252
253
253
254 def post_push(extras):
254 def post_push(extras):
255 """Hook executed after user pushes to the repository."""
255 """Hook executed after user pushes to the repository."""
256 commit_ids = extras.commit_ids
256 commit_ids = extras.commit_ids
257
257
258 # log the push call
258 # log the push call
259 audit_user = audit_logger.UserWrap(
259 audit_user = audit_logger.UserWrap(
260 username=extras.username, ip_addr=extras.ip)
260 username=extras.username, ip_addr=extras.ip)
261 repo = audit_logger.RepoWrap(repo_name=extras.repository)
261 repo = audit_logger.RepoWrap(repo_name=extras.repository)
262 audit_logger.store(
262 audit_logger.store(
263 'user.push', action_data={
263 'user.push', action_data={
264 'user_agent': extras.user_agent,
264 'user_agent': extras.user_agent,
265 'commit_ids': commit_ids[:400]},
265 'commit_ids': commit_ids[:400]},
266 user=audit_user, repo=repo, commit=True)
266 user=audit_user, repo=repo, commit=True)
267
267
268 # Propagate to external components.
268 # Propagate to external components.
269 output = ''
269 output = ''
270 # make lock is a tri state False, True, None. We only release lock on False
270 # make lock is a tri state False, True, None. We only release lock on False
271 if extras.make_lock is False and not is_shadow_repo(extras):
271 if extras.make_lock is False and not is_shadow_repo(extras):
272 Repository.unlock(Repository.get_by_repo_name(extras.repository))
272 Repository.unlock(Repository.get_by_repo_name(extras.repository))
273 msg = 'Released lock on repo `%s`\n' % extras.repository
273 msg = 'Released lock on repo `{}`\n'.format(safe_str(extras.repository))
274 output += msg
274 output += msg
275
275
276 if extras.locked_by[0]:
276 if extras.locked_by[0]:
277 locked_by = User.get(extras.locked_by[0]).username
277 locked_by = User.get(extras.locked_by[0]).username
278 reason = extras.locked_by[2]
278 reason = extras.locked_by[2]
279 _http_ret = HTTPLockedRC(
279 _http_ret = HTTPLockedRC(
280 _locked_by_explanation(extras.repository, locked_by, reason))
280 _locked_by_explanation(extras.repository, locked_by, reason))
281 # TODO: johbo: if not?
281 # TODO: johbo: if not?
282 if str(_http_ret.code).startswith('2'):
282 if str(_http_ret.code).startswith('2'):
283 # 2xx Codes don't raise exceptions
283 # 2xx Codes don't raise exceptions
284 output += _http_ret.title
284 output += _http_ret.title
285
285
286 if extras.new_refs:
286 if extras.new_refs:
287 tmpl = extras.server_url + '/' + extras.repository + \
287 tmpl = '{}/{}/pull-request/new?{{ref_type}}={{ref_name}}'.format(
288 "/pull-request/new?{ref_type}={ref_name}"
288 safe_str(extras.server_url), safe_str(extras.repository))
289
289
290 for branch_name in extras.new_refs['branches']:
290 for branch_name in extras.new_refs['branches']:
291 output += 'RhodeCode: open pull request link: {}\n'.format(
291 output += 'RhodeCode: open pull request link: {}\n'.format(
292 tmpl.format(ref_type='branch', ref_name=safe_str(branch_name)))
292 tmpl.format(ref_type='branch', ref_name=safe_str(branch_name)))
293
293
294 for book_name in extras.new_refs['bookmarks']:
294 for book_name in extras.new_refs['bookmarks']:
295 output += 'RhodeCode: open pull request link: {}\n'.format(
295 output += 'RhodeCode: open pull request link: {}\n'.format(
296 tmpl.format(ref_type='bookmark', ref_name=safe_str(book_name)))
296 tmpl.format(ref_type='bookmark', ref_name=safe_str(book_name)))
297
297
298 hook_response = ''
298 hook_response = ''
299 if not is_shadow_repo(extras):
299 if not is_shadow_repo(extras):
300 hook_response = post_push_extension(
300 hook_response = post_push_extension(
301 repo_store_path=Repository.base_path(),
301 repo_store_path=Repository.base_path(),
302 **extras)
302 **extras)
303 events.trigger(events.RepoPushEvent(
303 events.trigger(events.RepoPushEvent(
304 repo_name=extras.repository, pushed_commit_ids=commit_ids, extras=extras))
304 repo_name=extras.repository, pushed_commit_ids=commit_ids, extras=extras))
305
305
306 output += 'RhodeCode: push completed\n'
306 output += 'RhodeCode: push completed\n'
307 return HookResponse(0, output) + hook_response
307 return HookResponse(0, output) + hook_response
308
308
309
309
310 def _locked_by_explanation(repo_name, user_name, reason):
310 def _locked_by_explanation(repo_name, user_name, reason):
311 message = (
311 message = (
312 'Repository `%s` locked by user `%s`. Reason:`%s`'
312 'Repository `%s` locked by user `%s`. Reason:`%s`'
313 % (repo_name, user_name, reason))
313 % (repo_name, user_name, reason))
314 return message
314 return message
315
315
316
316
317 def check_allowed_create_user(user_dict, created_by, **kwargs):
317 def check_allowed_create_user(user_dict, created_by, **kwargs):
318 # pre create hooks
318 # pre create hooks
319 if pre_create_user.is_active():
319 if pre_create_user.is_active():
320 hook_result = pre_create_user(created_by=created_by, **user_dict)
320 hook_result = pre_create_user(created_by=created_by, **user_dict)
321 allowed = hook_result.status == 0
321 allowed = hook_result.status == 0
322 if not allowed:
322 if not allowed:
323 reason = hook_result.output
323 reason = hook_result.output
324 raise UserCreationError(reason)
324 raise UserCreationError(reason)
325
325
326
326
327 class ExtensionCallback(object):
327 class ExtensionCallback(object):
328 """
328 """
329 Forwards a given call to rcextensions, sanitizes keyword arguments.
329 Forwards a given call to rcextensions, sanitizes keyword arguments.
330
330
331 Does check if there is an extension active for that hook. If it is
331 Does check if there is an extension active for that hook. If it is
332 there, it will forward all `kwargs_keys` keyword arguments to the
332 there, it will forward all `kwargs_keys` keyword arguments to the
333 extension callback.
333 extension callback.
334 """
334 """
335
335
336 def __init__(self, hook_name, kwargs_keys):
336 def __init__(self, hook_name, kwargs_keys):
337 self._hook_name = hook_name
337 self._hook_name = hook_name
338 self._kwargs_keys = set(kwargs_keys)
338 self._kwargs_keys = set(kwargs_keys)
339
339
340 def __call__(self, *args, **kwargs):
340 def __call__(self, *args, **kwargs):
341 log.debug('Calling extension callback for `%s`', self._hook_name)
341 log.debug('Calling extension callback for `%s`', self._hook_name)
342 callback = self._get_callback()
342 callback = self._get_callback()
343 if not callback:
343 if not callback:
344 log.debug('extension callback `%s` not found, skipping...', self._hook_name)
344 log.debug('extension callback `%s` not found, skipping...', self._hook_name)
345 return
345 return
346
346
347 kwargs_to_pass = {}
347 kwargs_to_pass = {}
348 for key in self._kwargs_keys:
348 for key in self._kwargs_keys:
349 try:
349 try:
350 kwargs_to_pass[key] = kwargs[key]
350 kwargs_to_pass[key] = kwargs[key]
351 except KeyError:
351 except KeyError:
352 log.error('Failed to fetch %s key. Expected keys: %s',
352 log.error('Failed to fetch %s key. Expected keys: %s',
353 key, self._kwargs_keys)
353 key, self._kwargs_keys)
354 raise
354 raise
355
355
356 # backward compat for removed api_key for old hooks. This was it works
356 # backward compat for removed api_key for old hooks. This was it works
357 # with older rcextensions that require api_key present
357 # with older rcextensions that require api_key present
358 if self._hook_name in ['CREATE_USER_HOOK', 'DELETE_USER_HOOK']:
358 if self._hook_name in ['CREATE_USER_HOOK', 'DELETE_USER_HOOK']:
359 kwargs_to_pass['api_key'] = '_DEPRECATED_'
359 kwargs_to_pass['api_key'] = '_DEPRECATED_'
360 return callback(**kwargs_to_pass)
360 return callback(**kwargs_to_pass)
361
361
362 def is_active(self):
362 def is_active(self):
363 return hasattr(rhodecode.EXTENSIONS, self._hook_name)
363 return hasattr(rhodecode.EXTENSIONS, self._hook_name)
364
364
365 def _get_callback(self):
365 def _get_callback(self):
366 return getattr(rhodecode.EXTENSIONS, self._hook_name, None)
366 return getattr(rhodecode.EXTENSIONS, self._hook_name, None)
367
367
368
368
369 pre_pull_extension = ExtensionCallback(
369 pre_pull_extension = ExtensionCallback(
370 hook_name='PRE_PULL_HOOK',
370 hook_name='PRE_PULL_HOOK',
371 kwargs_keys=(
371 kwargs_keys=(
372 'server_url', 'config', 'scm', 'username', 'ip', 'action',
372 'server_url', 'config', 'scm', 'username', 'ip', 'action',
373 'repository', 'hook_type', 'user_agent', 'repo_store_path',))
373 'repository', 'hook_type', 'user_agent', 'repo_store_path',))
374
374
375
375
376 post_pull_extension = ExtensionCallback(
376 post_pull_extension = ExtensionCallback(
377 hook_name='PULL_HOOK',
377 hook_name='PULL_HOOK',
378 kwargs_keys=(
378 kwargs_keys=(
379 'server_url', 'config', 'scm', 'username', 'ip', 'action',
379 'server_url', 'config', 'scm', 'username', 'ip', 'action',
380 'repository', 'hook_type', 'user_agent', 'repo_store_path',))
380 'repository', 'hook_type', 'user_agent', 'repo_store_path',))
381
381
382
382
383 pre_push_extension = ExtensionCallback(
383 pre_push_extension = ExtensionCallback(
384 hook_name='PRE_PUSH_HOOK',
384 hook_name='PRE_PUSH_HOOK',
385 kwargs_keys=(
385 kwargs_keys=(
386 'server_url', 'config', 'scm', 'username', 'ip', 'action',
386 'server_url', 'config', 'scm', 'username', 'ip', 'action',
387 'repository', 'repo_store_path', 'commit_ids', 'hook_type', 'user_agent',))
387 'repository', 'repo_store_path', 'commit_ids', 'hook_type', 'user_agent',))
388
388
389
389
390 post_push_extension = ExtensionCallback(
390 post_push_extension = ExtensionCallback(
391 hook_name='PUSH_HOOK',
391 hook_name='PUSH_HOOK',
392 kwargs_keys=(
392 kwargs_keys=(
393 'server_url', 'config', 'scm', 'username', 'ip', 'action',
393 'server_url', 'config', 'scm', 'username', 'ip', 'action',
394 'repository', 'repo_store_path', 'commit_ids', 'hook_type', 'user_agent',))
394 'repository', 'repo_store_path', 'commit_ids', 'hook_type', 'user_agent',))
395
395
396
396
397 pre_create_user = ExtensionCallback(
397 pre_create_user = ExtensionCallback(
398 hook_name='PRE_CREATE_USER_HOOK',
398 hook_name='PRE_CREATE_USER_HOOK',
399 kwargs_keys=(
399 kwargs_keys=(
400 'username', 'password', 'email', 'firstname', 'lastname', 'active',
400 'username', 'password', 'email', 'firstname', 'lastname', 'active',
401 'admin', 'created_by'))
401 'admin', 'created_by'))
402
402
403
403
404 log_create_pull_request = ExtensionCallback(
404 log_create_pull_request = ExtensionCallback(
405 hook_name='CREATE_PULL_REQUEST',
405 hook_name='CREATE_PULL_REQUEST',
406 kwargs_keys=(
406 kwargs_keys=(
407 'server_url', 'config', 'scm', 'username', 'ip', 'action',
407 'server_url', 'config', 'scm', 'username', 'ip', 'action',
408 'repository', 'pull_request_id', 'url', 'title', 'description',
408 'repository', 'pull_request_id', 'url', 'title', 'description',
409 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
409 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
410 'mergeable', 'source', 'target', 'author', 'reviewers'))
410 'mergeable', 'source', 'target', 'author', 'reviewers'))
411
411
412
412
413 log_merge_pull_request = ExtensionCallback(
413 log_merge_pull_request = ExtensionCallback(
414 hook_name='MERGE_PULL_REQUEST',
414 hook_name='MERGE_PULL_REQUEST',
415 kwargs_keys=(
415 kwargs_keys=(
416 'server_url', 'config', 'scm', 'username', 'ip', 'action',
416 'server_url', 'config', 'scm', 'username', 'ip', 'action',
417 'repository', 'pull_request_id', 'url', 'title', 'description',
417 'repository', 'pull_request_id', 'url', 'title', 'description',
418 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
418 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
419 'mergeable', 'source', 'target', 'author', 'reviewers'))
419 'mergeable', 'source', 'target', 'author', 'reviewers'))
420
420
421
421
422 log_close_pull_request = ExtensionCallback(
422 log_close_pull_request = ExtensionCallback(
423 hook_name='CLOSE_PULL_REQUEST',
423 hook_name='CLOSE_PULL_REQUEST',
424 kwargs_keys=(
424 kwargs_keys=(
425 'server_url', 'config', 'scm', 'username', 'ip', 'action',
425 'server_url', 'config', 'scm', 'username', 'ip', 'action',
426 'repository', 'pull_request_id', 'url', 'title', 'description',
426 'repository', 'pull_request_id', 'url', 'title', 'description',
427 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
427 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
428 'mergeable', 'source', 'target', 'author', 'reviewers'))
428 'mergeable', 'source', 'target', 'author', 'reviewers'))
429
429
430
430
431 log_review_pull_request = ExtensionCallback(
431 log_review_pull_request = ExtensionCallback(
432 hook_name='REVIEW_PULL_REQUEST',
432 hook_name='REVIEW_PULL_REQUEST',
433 kwargs_keys=(
433 kwargs_keys=(
434 'server_url', 'config', 'scm', 'username', 'ip', 'action',
434 'server_url', 'config', 'scm', 'username', 'ip', 'action',
435 'repository', 'pull_request_id', 'url', 'title', 'description',
435 'repository', 'pull_request_id', 'url', 'title', 'description',
436 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
436 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
437 'mergeable', 'source', 'target', 'author', 'reviewers'))
437 'mergeable', 'source', 'target', 'author', 'reviewers'))
438
438
439
439
440 log_update_pull_request = ExtensionCallback(
440 log_update_pull_request = ExtensionCallback(
441 hook_name='UPDATE_PULL_REQUEST',
441 hook_name='UPDATE_PULL_REQUEST',
442 kwargs_keys=(
442 kwargs_keys=(
443 'server_url', 'config', 'scm', 'username', 'ip', 'action',
443 'server_url', 'config', 'scm', 'username', 'ip', 'action',
444 'repository', 'pull_request_id', 'url', 'title', 'description',
444 'repository', 'pull_request_id', 'url', 'title', 'description',
445 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
445 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status',
446 'mergeable', 'source', 'target', 'author', 'reviewers'))
446 'mergeable', 'source', 'target', 'author', 'reviewers'))
447
447
448
448
449 log_create_user = ExtensionCallback(
449 log_create_user = ExtensionCallback(
450 hook_name='CREATE_USER_HOOK',
450 hook_name='CREATE_USER_HOOK',
451 kwargs_keys=(
451 kwargs_keys=(
452 'username', 'full_name_or_username', 'full_contact', 'user_id',
452 'username', 'full_name_or_username', 'full_contact', 'user_id',
453 'name', 'firstname', 'short_contact', 'admin', 'lastname',
453 'name', 'firstname', 'short_contact', 'admin', 'lastname',
454 'ip_addresses', 'extern_type', 'extern_name',
454 'ip_addresses', 'extern_type', 'extern_name',
455 'email', 'api_keys', 'last_login',
455 'email', 'api_keys', 'last_login',
456 'full_name', 'active', 'password', 'emails',
456 'full_name', 'active', 'password', 'emails',
457 'inherit_default_permissions', 'created_by', 'created_on'))
457 'inherit_default_permissions', 'created_by', 'created_on'))
458
458
459
459
460 log_delete_user = ExtensionCallback(
460 log_delete_user = ExtensionCallback(
461 hook_name='DELETE_USER_HOOK',
461 hook_name='DELETE_USER_HOOK',
462 kwargs_keys=(
462 kwargs_keys=(
463 'username', 'full_name_or_username', 'full_contact', 'user_id',
463 'username', 'full_name_or_username', 'full_contact', 'user_id',
464 'name', 'firstname', 'short_contact', 'admin', 'lastname',
464 'name', 'firstname', 'short_contact', 'admin', 'lastname',
465 'ip_addresses',
465 'ip_addresses',
466 'email', 'last_login',
466 'email', 'last_login',
467 'full_name', 'active', 'password', 'emails',
467 'full_name', 'active', 'password', 'emails',
468 'inherit_default_permissions', 'deleted_by'))
468 'inherit_default_permissions', 'deleted_by'))
469
469
470
470
471 log_create_repository = ExtensionCallback(
471 log_create_repository = ExtensionCallback(
472 hook_name='CREATE_REPO_HOOK',
472 hook_name='CREATE_REPO_HOOK',
473 kwargs_keys=(
473 kwargs_keys=(
474 'repo_name', 'repo_type', 'description', 'private', 'created_on',
474 'repo_name', 'repo_type', 'description', 'private', 'created_on',
475 'enable_downloads', 'repo_id', 'user_id', 'enable_statistics',
475 'enable_downloads', 'repo_id', 'user_id', 'enable_statistics',
476 'clone_uri', 'fork_id', 'group_id', 'created_by'))
476 'clone_uri', 'fork_id', 'group_id', 'created_by'))
477
477
478
478
479 log_delete_repository = ExtensionCallback(
479 log_delete_repository = ExtensionCallback(
480 hook_name='DELETE_REPO_HOOK',
480 hook_name='DELETE_REPO_HOOK',
481 kwargs_keys=(
481 kwargs_keys=(
482 'repo_name', 'repo_type', 'description', 'private', 'created_on',
482 'repo_name', 'repo_type', 'description', 'private', 'created_on',
483 'enable_downloads', 'repo_id', 'user_id', 'enable_statistics',
483 'enable_downloads', 'repo_id', 'user_id', 'enable_statistics',
484 'clone_uri', 'fork_id', 'group_id', 'deleted_by', 'deleted_on'))
484 'clone_uri', 'fork_id', 'group_id', 'deleted_by', 'deleted_on'))
485
485
486
486
487 log_create_repository_group = ExtensionCallback(
487 log_create_repository_group = ExtensionCallback(
488 hook_name='CREATE_REPO_GROUP_HOOK',
488 hook_name='CREATE_REPO_GROUP_HOOK',
489 kwargs_keys=(
489 kwargs_keys=(
490 'group_name', 'group_parent_id', 'group_description',
490 'group_name', 'group_parent_id', 'group_description',
491 'group_id', 'user_id', 'created_by', 'created_on',
491 'group_id', 'user_id', 'created_by', 'created_on',
492 'enable_locking'))
492 'enable_locking'))
General Comments 0
You need to be logged in to leave comments. Login now