##// END OF EJS Templates
issue-tracker: fix prefix to be escaped as well as the url pattern.
marcink -
r2448:c5bccf36 default
parent child Browse files
Show More
@@ -1,826 +1,826 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2017 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 import os
22 22 import hashlib
23 23 import logging
24 24 from collections import namedtuple
25 25 from functools import wraps
26 26 import bleach
27 27
28 28 from rhodecode.lib import caches
29 29 from rhodecode.lib.utils2 import (
30 30 Optional, AttributeDict, safe_str, remove_prefix, str2bool)
31 31 from rhodecode.lib.vcs.backends import base
32 32 from rhodecode.model import BaseModel
33 33 from rhodecode.model.db import (
34 34 RepoRhodeCodeUi, RepoRhodeCodeSetting, RhodeCodeUi, RhodeCodeSetting)
35 35 from rhodecode.model.meta import Session
36 36
37 37
38 38 log = logging.getLogger(__name__)
39 39
40 40
41 41 UiSetting = namedtuple(
42 42 'UiSetting', ['section', 'key', 'value', 'active'])
43 43
44 44 SOCIAL_PLUGINS_LIST = ['github', 'bitbucket', 'twitter', 'google']
45 45
46 46
47 47 class SettingNotFound(Exception):
48 48 def __init__(self, setting_id):
49 49 msg = 'Setting `{}` is not found'.format(setting_id)
50 50 super(SettingNotFound, self).__init__(msg)
51 51
52 52
53 53 class SettingsModel(BaseModel):
54 54 BUILTIN_HOOKS = (
55 55 RhodeCodeUi.HOOK_REPO_SIZE, RhodeCodeUi.HOOK_PUSH,
56 56 RhodeCodeUi.HOOK_PRE_PUSH, RhodeCodeUi.HOOK_PRETX_PUSH,
57 57 RhodeCodeUi.HOOK_PULL, RhodeCodeUi.HOOK_PRE_PULL,
58 58 RhodeCodeUi.HOOK_PUSH_KEY,)
59 59 HOOKS_SECTION = 'hooks'
60 60
61 61 def __init__(self, sa=None, repo=None):
62 62 self.repo = repo
63 63 self.UiDbModel = RepoRhodeCodeUi if repo else RhodeCodeUi
64 64 self.SettingsDbModel = (
65 65 RepoRhodeCodeSetting if repo else RhodeCodeSetting)
66 66 super(SettingsModel, self).__init__(sa)
67 67
68 68 def get_ui_by_key(self, key):
69 69 q = self.UiDbModel.query()
70 70 q = q.filter(self.UiDbModel.ui_key == key)
71 71 q = self._filter_by_repo(RepoRhodeCodeUi, q)
72 72 return q.scalar()
73 73
74 74 def get_ui_by_section(self, section):
75 75 q = self.UiDbModel.query()
76 76 q = q.filter(self.UiDbModel.ui_section == section)
77 77 q = self._filter_by_repo(RepoRhodeCodeUi, q)
78 78 return q.all()
79 79
80 80 def get_ui_by_section_and_key(self, section, key):
81 81 q = self.UiDbModel.query()
82 82 q = q.filter(self.UiDbModel.ui_section == section)
83 83 q = q.filter(self.UiDbModel.ui_key == key)
84 84 q = self._filter_by_repo(RepoRhodeCodeUi, q)
85 85 return q.scalar()
86 86
87 87 def get_ui(self, section=None, key=None):
88 88 q = self.UiDbModel.query()
89 89 q = self._filter_by_repo(RepoRhodeCodeUi, q)
90 90
91 91 if section:
92 92 q = q.filter(self.UiDbModel.ui_section == section)
93 93 if key:
94 94 q = q.filter(self.UiDbModel.ui_key == key)
95 95
96 96 # TODO: mikhail: add caching
97 97 result = [
98 98 UiSetting(
99 99 section=safe_str(r.ui_section), key=safe_str(r.ui_key),
100 100 value=safe_str(r.ui_value), active=r.ui_active
101 101 )
102 102 for r in q.all()
103 103 ]
104 104 return result
105 105
106 106 def get_builtin_hooks(self):
107 107 q = self.UiDbModel.query()
108 108 q = q.filter(self.UiDbModel.ui_key.in_(self.BUILTIN_HOOKS))
109 109 return self._get_hooks(q)
110 110
111 111 def get_custom_hooks(self):
112 112 q = self.UiDbModel.query()
113 113 q = q.filter(~self.UiDbModel.ui_key.in_(self.BUILTIN_HOOKS))
114 114 return self._get_hooks(q)
115 115
116 116 def create_ui_section_value(self, section, val, key=None, active=True):
117 117 new_ui = self.UiDbModel()
118 118 new_ui.ui_section = section
119 119 new_ui.ui_value = val
120 120 new_ui.ui_active = active
121 121
122 122 if self.repo:
123 123 repo = self._get_repo(self.repo)
124 124 repository_id = repo.repo_id
125 125 new_ui.repository_id = repository_id
126 126
127 127 if not key:
128 128 # keys are unique so they need appended info
129 129 if self.repo:
130 130 key = hashlib.sha1(
131 131 '{}{}{}'.format(section, val, repository_id)).hexdigest()
132 132 else:
133 133 key = hashlib.sha1('{}{}'.format(section, val)).hexdigest()
134 134
135 135 new_ui.ui_key = key
136 136
137 137 Session().add(new_ui)
138 138 return new_ui
139 139
140 140 def create_or_update_hook(self, key, value):
141 141 ui = (
142 142 self.get_ui_by_section_and_key(self.HOOKS_SECTION, key) or
143 143 self.UiDbModel())
144 144 ui.ui_section = self.HOOKS_SECTION
145 145 ui.ui_active = True
146 146 ui.ui_key = key
147 147 ui.ui_value = value
148 148
149 149 if self.repo:
150 150 repo = self._get_repo(self.repo)
151 151 repository_id = repo.repo_id
152 152 ui.repository_id = repository_id
153 153
154 154 Session().add(ui)
155 155 return ui
156 156
157 157 def delete_ui(self, id_):
158 158 ui = self.UiDbModel.get(id_)
159 159 if not ui:
160 160 raise SettingNotFound(id_)
161 161 Session().delete(ui)
162 162
163 163 def get_setting_by_name(self, name):
164 164 q = self._get_settings_query()
165 165 q = q.filter(self.SettingsDbModel.app_settings_name == name)
166 166 return q.scalar()
167 167
168 168 def create_or_update_setting(
169 169 self, name, val=Optional(''), type_=Optional('unicode')):
170 170 """
171 171 Creates or updates RhodeCode setting. If updates is triggered it will
172 172 only update parameters that are explicityl set Optional instance will
173 173 be skipped
174 174
175 175 :param name:
176 176 :param val:
177 177 :param type_:
178 178 :return:
179 179 """
180 180
181 181 res = self.get_setting_by_name(name)
182 182 repo = self._get_repo(self.repo) if self.repo else None
183 183
184 184 if not res:
185 185 val = Optional.extract(val)
186 186 type_ = Optional.extract(type_)
187 187
188 188 args = (
189 189 (repo.repo_id, name, val, type_)
190 190 if repo else (name, val, type_))
191 191 res = self.SettingsDbModel(*args)
192 192
193 193 else:
194 194 if self.repo:
195 195 res.repository_id = repo.repo_id
196 196
197 197 res.app_settings_name = name
198 198 if not isinstance(type_, Optional):
199 199 # update if set
200 200 res.app_settings_type = type_
201 201 if not isinstance(val, Optional):
202 202 # update if set
203 203 res.app_settings_value = val
204 204
205 205 Session().add(res)
206 206 return res
207 207
208 208 def invalidate_settings_cache(self):
209 209 namespace = 'rhodecode_settings'
210 210 cache_manager = caches.get_cache_manager('sql_cache_short', namespace)
211 211 caches.clear_cache_manager(cache_manager)
212 212
213 213 def get_all_settings(self, cache=False):
214 214
215 215 def _compute():
216 216 q = self._get_settings_query()
217 217 if not q:
218 218 raise Exception('Could not get application settings !')
219 219
220 220 settings = {
221 221 'rhodecode_' + result.app_settings_name: result.app_settings_value
222 222 for result in q
223 223 }
224 224 return settings
225 225
226 226 if cache:
227 227 log.debug('Fetching app settings using cache')
228 228 repo = self._get_repo(self.repo) if self.repo else None
229 229 namespace = 'rhodecode_settings'
230 230 cache_manager = caches.get_cache_manager(
231 231 'sql_cache_short', namespace)
232 232 _cache_key = (
233 233 "get_repo_{}_settings".format(repo.repo_id)
234 234 if repo else "get_app_settings")
235 235
236 236 return cache_manager.get(_cache_key, createfunc=_compute)
237 237
238 238 else:
239 239 return _compute()
240 240
241 241 def get_auth_settings(self):
242 242 q = self._get_settings_query()
243 243 q = q.filter(
244 244 self.SettingsDbModel.app_settings_name.startswith('auth_'))
245 245 rows = q.all()
246 246 auth_settings = {
247 247 row.app_settings_name: row.app_settings_value for row in rows}
248 248 return auth_settings
249 249
250 250 def get_auth_plugins(self):
251 251 auth_plugins = self.get_setting_by_name("auth_plugins")
252 252 return auth_plugins.app_settings_value
253 253
254 254 def get_default_repo_settings(self, strip_prefix=False):
255 255 q = self._get_settings_query()
256 256 q = q.filter(
257 257 self.SettingsDbModel.app_settings_name.startswith('default_'))
258 258 rows = q.all()
259 259
260 260 result = {}
261 261 for row in rows:
262 262 key = row.app_settings_name
263 263 if strip_prefix:
264 264 key = remove_prefix(key, prefix='default_')
265 265 result.update({key: row.app_settings_value})
266 266 return result
267 267
268 268 def get_repo(self):
269 269 repo = self._get_repo(self.repo)
270 270 if not repo:
271 271 raise Exception(
272 272 'Repository `{}` cannot be found inside the database'.format(
273 273 self.repo))
274 274 return repo
275 275
276 276 def _filter_by_repo(self, model, query):
277 277 if self.repo:
278 278 repo = self.get_repo()
279 279 query = query.filter(model.repository_id == repo.repo_id)
280 280 return query
281 281
282 282 def _get_hooks(self, query):
283 283 query = query.filter(self.UiDbModel.ui_section == self.HOOKS_SECTION)
284 284 query = self._filter_by_repo(RepoRhodeCodeUi, query)
285 285 return query.all()
286 286
287 287 def _get_settings_query(self):
288 288 q = self.SettingsDbModel.query()
289 289 return self._filter_by_repo(RepoRhodeCodeSetting, q)
290 290
291 291 def list_enabled_social_plugins(self, settings):
292 292 enabled = []
293 293 for plug in SOCIAL_PLUGINS_LIST:
294 294 if str2bool(settings.get('rhodecode_auth_{}_enabled'.format(plug)
295 295 )):
296 296 enabled.append(plug)
297 297 return enabled
298 298
299 299
300 300 def assert_repo_settings(func):
301 301 @wraps(func)
302 302 def _wrapper(self, *args, **kwargs):
303 303 if not self.repo_settings:
304 304 raise Exception('Repository is not specified')
305 305 return func(self, *args, **kwargs)
306 306 return _wrapper
307 307
308 308
309 309 class IssueTrackerSettingsModel(object):
310 310 INHERIT_SETTINGS = 'inherit_issue_tracker_settings'
311 311 SETTINGS_PREFIX = 'issuetracker_'
312 312
313 313 def __init__(self, sa=None, repo=None):
314 314 self.global_settings = SettingsModel(sa=sa)
315 315 self.repo_settings = SettingsModel(sa=sa, repo=repo) if repo else None
316 316
317 317 @property
318 318 def inherit_global_settings(self):
319 319 if not self.repo_settings:
320 320 return True
321 321 setting = self.repo_settings.get_setting_by_name(self.INHERIT_SETTINGS)
322 322 return setting.app_settings_value if setting else True
323 323
324 324 @inherit_global_settings.setter
325 325 def inherit_global_settings(self, value):
326 326 if self.repo_settings:
327 327 settings = self.repo_settings.create_or_update_setting(
328 328 self.INHERIT_SETTINGS, value, type_='bool')
329 329 Session().add(settings)
330 330
331 331 def _get_keyname(self, key, uid, prefix=''):
332 332 return '{0}{1}{2}_{3}'.format(
333 333 prefix, self.SETTINGS_PREFIX, key, uid)
334 334
335 335 def _make_dict_for_settings(self, qs):
336 336 prefix_match = self._get_keyname('pat', '', 'rhodecode_')
337 337
338 338 issuetracker_entries = {}
339 339 # create keys
340 340 for k, v in qs.items():
341 341 if k.startswith(prefix_match):
342 342 uid = k[len(prefix_match):]
343 343 issuetracker_entries[uid] = None
344 344
345 345 # populate
346 346 for uid in issuetracker_entries:
347 347 issuetracker_entries[uid] = AttributeDict({
348 348 'pat': qs.get(
349 349 self._get_keyname('pat', uid, 'rhodecode_')),
350 350 'url': bleach.clean(
351 351 qs.get(self._get_keyname('url', uid, 'rhodecode_')) or ''),
352 'pref': qs.get(
353 self._get_keyname('pref', uid, 'rhodecode_')),
352 'pref': bleach.clean(
353 qs.get(self._get_keyname('pref', uid, 'rhodecode_')) or ''),
354 354 'desc': qs.get(
355 355 self._get_keyname('desc', uid, 'rhodecode_')),
356 356 })
357 357 return issuetracker_entries
358 358
359 359 def get_global_settings(self, cache=False):
360 360 """
361 361 Returns list of global issue tracker settings
362 362 """
363 363 defaults = self.global_settings.get_all_settings(cache=cache)
364 364 settings = self._make_dict_for_settings(defaults)
365 365 return settings
366 366
367 367 def get_repo_settings(self, cache=False):
368 368 """
369 369 Returns list of issue tracker settings per repository
370 370 """
371 371 if not self.repo_settings:
372 372 raise Exception('Repository is not specified')
373 373 all_settings = self.repo_settings.get_all_settings(cache=cache)
374 374 settings = self._make_dict_for_settings(all_settings)
375 375 return settings
376 376
377 377 def get_settings(self, cache=False):
378 378 if self.inherit_global_settings:
379 379 return self.get_global_settings(cache=cache)
380 380 else:
381 381 return self.get_repo_settings(cache=cache)
382 382
383 383 def delete_entries(self, uid):
384 384 if self.repo_settings:
385 385 all_patterns = self.get_repo_settings()
386 386 settings_model = self.repo_settings
387 387 else:
388 388 all_patterns = self.get_global_settings()
389 389 settings_model = self.global_settings
390 390 entries = all_patterns.get(uid, [])
391 391
392 392 for del_key in entries:
393 393 setting_name = self._get_keyname(del_key, uid)
394 394 entry = settings_model.get_setting_by_name(setting_name)
395 395 if entry:
396 396 Session().delete(entry)
397 397
398 398 Session().commit()
399 399
400 400 def create_or_update_setting(
401 401 self, name, val=Optional(''), type_=Optional('unicode')):
402 402 if self.repo_settings:
403 403 setting = self.repo_settings.create_or_update_setting(
404 404 name, val, type_)
405 405 else:
406 406 setting = self.global_settings.create_or_update_setting(
407 407 name, val, type_)
408 408 return setting
409 409
410 410
411 411 class VcsSettingsModel(object):
412 412
413 413 INHERIT_SETTINGS = 'inherit_vcs_settings'
414 414 GENERAL_SETTINGS = (
415 415 'use_outdated_comments',
416 416 'pr_merge_enabled',
417 417 'hg_use_rebase_for_merging',
418 418 'hg_close_branch_before_merging',
419 419 'git_use_rebase_for_merging',
420 420 'git_close_branch_before_merging')
421 421
422 422 HOOKS_SETTINGS = (
423 423 ('hooks', 'changegroup.repo_size'),
424 424 ('hooks', 'changegroup.push_logger'),
425 425 ('hooks', 'outgoing.pull_logger'),)
426 426 HG_SETTINGS = (
427 427 ('extensions', 'largefiles'),
428 428 ('phases', 'publish'),
429 429 ('extensions', 'evolve'),)
430 430 GIT_SETTINGS = (
431 431 ('vcs_git_lfs', 'enabled'),)
432 432 GLOBAL_HG_SETTINGS = (
433 433 ('extensions', 'largefiles'),
434 434 ('largefiles', 'usercache'),
435 435 ('phases', 'publish'),
436 436 ('extensions', 'hgsubversion'),
437 437 ('extensions', 'evolve'),)
438 438 GLOBAL_GIT_SETTINGS = (
439 439 ('vcs_git_lfs', 'enabled'),
440 440 ('vcs_git_lfs', 'store_location'))
441 441 GLOBAL_SVN_SETTINGS = (
442 442 ('vcs_svn_proxy', 'http_requests_enabled'),
443 443 ('vcs_svn_proxy', 'http_server_url'))
444 444
445 445 SVN_BRANCH_SECTION = 'vcs_svn_branch'
446 446 SVN_TAG_SECTION = 'vcs_svn_tag'
447 447 SSL_SETTING = ('web', 'push_ssl')
448 448 PATH_SETTING = ('paths', '/')
449 449
450 450 def __init__(self, sa=None, repo=None):
451 451 self.global_settings = SettingsModel(sa=sa)
452 452 self.repo_settings = SettingsModel(sa=sa, repo=repo) if repo else None
453 453 self._ui_settings = (
454 454 self.HG_SETTINGS + self.GIT_SETTINGS + self.HOOKS_SETTINGS)
455 455 self._svn_sections = (self.SVN_BRANCH_SECTION, self.SVN_TAG_SECTION)
456 456
457 457 @property
458 458 @assert_repo_settings
459 459 def inherit_global_settings(self):
460 460 setting = self.repo_settings.get_setting_by_name(self.INHERIT_SETTINGS)
461 461 return setting.app_settings_value if setting else True
462 462
463 463 @inherit_global_settings.setter
464 464 @assert_repo_settings
465 465 def inherit_global_settings(self, value):
466 466 self.repo_settings.create_or_update_setting(
467 467 self.INHERIT_SETTINGS, value, type_='bool')
468 468
469 469 def get_global_svn_branch_patterns(self):
470 470 return self.global_settings.get_ui_by_section(self.SVN_BRANCH_SECTION)
471 471
472 472 @assert_repo_settings
473 473 def get_repo_svn_branch_patterns(self):
474 474 return self.repo_settings.get_ui_by_section(self.SVN_BRANCH_SECTION)
475 475
476 476 def get_global_svn_tag_patterns(self):
477 477 return self.global_settings.get_ui_by_section(self.SVN_TAG_SECTION)
478 478
479 479 @assert_repo_settings
480 480 def get_repo_svn_tag_patterns(self):
481 481 return self.repo_settings.get_ui_by_section(self.SVN_TAG_SECTION)
482 482
483 483 def get_global_settings(self):
484 484 return self._collect_all_settings(global_=True)
485 485
486 486 @assert_repo_settings
487 487 def get_repo_settings(self):
488 488 return self._collect_all_settings(global_=False)
489 489
490 490 @assert_repo_settings
491 491 def create_or_update_repo_settings(
492 492 self, data, inherit_global_settings=False):
493 493 from rhodecode.model.scm import ScmModel
494 494
495 495 self.inherit_global_settings = inherit_global_settings
496 496
497 497 repo = self.repo_settings.get_repo()
498 498 if not inherit_global_settings:
499 499 if repo.repo_type == 'svn':
500 500 self.create_repo_svn_settings(data)
501 501 else:
502 502 self.create_or_update_repo_hook_settings(data)
503 503 self.create_or_update_repo_pr_settings(data)
504 504
505 505 if repo.repo_type == 'hg':
506 506 self.create_or_update_repo_hg_settings(data)
507 507
508 508 if repo.repo_type == 'git':
509 509 self.create_or_update_repo_git_settings(data)
510 510
511 511 ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
512 512
513 513 @assert_repo_settings
514 514 def create_or_update_repo_hook_settings(self, data):
515 515 for section, key in self.HOOKS_SETTINGS:
516 516 data_key = self._get_form_ui_key(section, key)
517 517 if data_key not in data:
518 518 raise ValueError(
519 519 'The given data does not contain {} key'.format(data_key))
520 520
521 521 active = data.get(data_key)
522 522 repo_setting = self.repo_settings.get_ui_by_section_and_key(
523 523 section, key)
524 524 if not repo_setting:
525 525 global_setting = self.global_settings.\
526 526 get_ui_by_section_and_key(section, key)
527 527 self.repo_settings.create_ui_section_value(
528 528 section, global_setting.ui_value, key=key, active=active)
529 529 else:
530 530 repo_setting.ui_active = active
531 531 Session().add(repo_setting)
532 532
533 533 def update_global_hook_settings(self, data):
534 534 for section, key in self.HOOKS_SETTINGS:
535 535 data_key = self._get_form_ui_key(section, key)
536 536 if data_key not in data:
537 537 raise ValueError(
538 538 'The given data does not contain {} key'.format(data_key))
539 539 active = data.get(data_key)
540 540 repo_setting = self.global_settings.get_ui_by_section_and_key(
541 541 section, key)
542 542 repo_setting.ui_active = active
543 543 Session().add(repo_setting)
544 544
545 545 @assert_repo_settings
546 546 def create_or_update_repo_pr_settings(self, data):
547 547 return self._create_or_update_general_settings(
548 548 self.repo_settings, data)
549 549
550 550 def create_or_update_global_pr_settings(self, data):
551 551 return self._create_or_update_general_settings(
552 552 self.global_settings, data)
553 553
554 554 @assert_repo_settings
555 555 def create_repo_svn_settings(self, data):
556 556 return self._create_svn_settings(self.repo_settings, data)
557 557
558 558 @assert_repo_settings
559 559 def create_or_update_repo_hg_settings(self, data):
560 560 largefiles, phases, evolve = \
561 561 self.HG_SETTINGS
562 562 largefiles_key, phases_key, evolve_key = \
563 563 self._get_settings_keys(self.HG_SETTINGS, data)
564 564
565 565 self._create_or_update_ui(
566 566 self.repo_settings, *largefiles, value='',
567 567 active=data[largefiles_key])
568 568 self._create_or_update_ui(
569 569 self.repo_settings, *evolve, value='',
570 570 active=data[evolve_key])
571 571 self._create_or_update_ui(
572 572 self.repo_settings, *phases, value=safe_str(data[phases_key]))
573 573
574 574 def create_or_update_global_hg_settings(self, data):
575 575 largefiles, largefiles_store, phases, hgsubversion, evolve \
576 576 = self.GLOBAL_HG_SETTINGS
577 577 largefiles_key, largefiles_store_key, phases_key, subversion_key, evolve_key \
578 578 = self._get_settings_keys(self.GLOBAL_HG_SETTINGS, data)
579 579
580 580 self._create_or_update_ui(
581 581 self.global_settings, *largefiles, value='',
582 582 active=data[largefiles_key])
583 583 self._create_or_update_ui(
584 584 self.global_settings, *largefiles_store,
585 585 value=data[largefiles_store_key])
586 586 self._create_or_update_ui(
587 587 self.global_settings, *phases, value=safe_str(data[phases_key]))
588 588 self._create_or_update_ui(
589 589 self.global_settings, *hgsubversion, active=data[subversion_key])
590 590 self._create_or_update_ui(
591 591 self.global_settings, *evolve, value='',
592 592 active=data[evolve_key])
593 593
594 594 def create_or_update_repo_git_settings(self, data):
595 595 # NOTE(marcink): # comma make unpack work properly
596 596 lfs_enabled, \
597 597 = self.GIT_SETTINGS
598 598
599 599 lfs_enabled_key, \
600 600 = self._get_settings_keys(self.GIT_SETTINGS, data)
601 601
602 602 self._create_or_update_ui(
603 603 self.repo_settings, *lfs_enabled, value=data[lfs_enabled_key],
604 604 active=data[lfs_enabled_key])
605 605
606 606 def create_or_update_global_git_settings(self, data):
607 607 lfs_enabled, lfs_store_location \
608 608 = self.GLOBAL_GIT_SETTINGS
609 609 lfs_enabled_key, lfs_store_location_key \
610 610 = self._get_settings_keys(self.GLOBAL_GIT_SETTINGS, data)
611 611
612 612 self._create_or_update_ui(
613 613 self.global_settings, *lfs_enabled, value=data[lfs_enabled_key],
614 614 active=data[lfs_enabled_key])
615 615 self._create_or_update_ui(
616 616 self.global_settings, *lfs_store_location,
617 617 value=data[lfs_store_location_key])
618 618
619 619 def create_or_update_global_svn_settings(self, data):
620 620 # branch/tags patterns
621 621 self._create_svn_settings(self.global_settings, data)
622 622
623 623 http_requests_enabled, http_server_url = self.GLOBAL_SVN_SETTINGS
624 624 http_requests_enabled_key, http_server_url_key = self._get_settings_keys(
625 625 self.GLOBAL_SVN_SETTINGS, data)
626 626
627 627 self._create_or_update_ui(
628 628 self.global_settings, *http_requests_enabled,
629 629 value=safe_str(data[http_requests_enabled_key]))
630 630 self._create_or_update_ui(
631 631 self.global_settings, *http_server_url,
632 632 value=data[http_server_url_key])
633 633
634 634 def update_global_ssl_setting(self, value):
635 635 self._create_or_update_ui(
636 636 self.global_settings, *self.SSL_SETTING, value=value)
637 637
638 638 def update_global_path_setting(self, value):
639 639 self._create_or_update_ui(
640 640 self.global_settings, *self.PATH_SETTING, value=value)
641 641
642 642 @assert_repo_settings
643 643 def delete_repo_svn_pattern(self, id_):
644 644 ui = self.repo_settings.UiDbModel.get(id_)
645 645 if ui and ui.repository.repo_name == self.repo_settings.repo:
646 646 # only delete if it's the same repo as initialized settings
647 647 self.repo_settings.delete_ui(id_)
648 648 else:
649 649 # raise error as if we wouldn't find this option
650 650 self.repo_settings.delete_ui(-1)
651 651
652 652 def delete_global_svn_pattern(self, id_):
653 653 self.global_settings.delete_ui(id_)
654 654
655 655 @assert_repo_settings
656 656 def get_repo_ui_settings(self, section=None, key=None):
657 657 global_uis = self.global_settings.get_ui(section, key)
658 658 repo_uis = self.repo_settings.get_ui(section, key)
659 659 filtered_repo_uis = self._filter_ui_settings(repo_uis)
660 660 filtered_repo_uis_keys = [
661 661 (s.section, s.key) for s in filtered_repo_uis]
662 662
663 663 def _is_global_ui_filtered(ui):
664 664 return (
665 665 (ui.section, ui.key) in filtered_repo_uis_keys
666 666 or ui.section in self._svn_sections)
667 667
668 668 filtered_global_uis = [
669 669 ui for ui in global_uis if not _is_global_ui_filtered(ui)]
670 670
671 671 return filtered_global_uis + filtered_repo_uis
672 672
673 673 def get_global_ui_settings(self, section=None, key=None):
674 674 return self.global_settings.get_ui(section, key)
675 675
676 676 def get_ui_settings_as_config_obj(self, section=None, key=None):
677 677 config = base.Config()
678 678
679 679 ui_settings = self.get_ui_settings(section=section, key=key)
680 680
681 681 for entry in ui_settings:
682 682 config.set(entry.section, entry.key, entry.value)
683 683
684 684 return config
685 685
686 686 def get_ui_settings(self, section=None, key=None):
687 687 if not self.repo_settings or self.inherit_global_settings:
688 688 return self.get_global_ui_settings(section, key)
689 689 else:
690 690 return self.get_repo_ui_settings(section, key)
691 691
692 692 def get_svn_patterns(self, section=None):
693 693 if not self.repo_settings:
694 694 return self.get_global_ui_settings(section)
695 695 else:
696 696 return self.get_repo_ui_settings(section)
697 697
698 698 @assert_repo_settings
699 699 def get_repo_general_settings(self):
700 700 global_settings = self.global_settings.get_all_settings()
701 701 repo_settings = self.repo_settings.get_all_settings()
702 702 filtered_repo_settings = self._filter_general_settings(repo_settings)
703 703 global_settings.update(filtered_repo_settings)
704 704 return global_settings
705 705
706 706 def get_global_general_settings(self):
707 707 return self.global_settings.get_all_settings()
708 708
709 709 def get_general_settings(self):
710 710 if not self.repo_settings or self.inherit_global_settings:
711 711 return self.get_global_general_settings()
712 712 else:
713 713 return self.get_repo_general_settings()
714 714
715 715 def get_repos_location(self):
716 716 return self.global_settings.get_ui_by_key('/').ui_value
717 717
718 718 def _filter_ui_settings(self, settings):
719 719 filtered_settings = [
720 720 s for s in settings if self._should_keep_setting(s)]
721 721 return filtered_settings
722 722
723 723 def _should_keep_setting(self, setting):
724 724 keep = (
725 725 (setting.section, setting.key) in self._ui_settings or
726 726 setting.section in self._svn_sections)
727 727 return keep
728 728
729 729 def _filter_general_settings(self, settings):
730 730 keys = ['rhodecode_{}'.format(key) for key in self.GENERAL_SETTINGS]
731 731 return {
732 732 k: settings[k]
733 733 for k in settings if k in keys}
734 734
735 735 def _collect_all_settings(self, global_=False):
736 736 settings = self.global_settings if global_ else self.repo_settings
737 737 result = {}
738 738
739 739 for section, key in self._ui_settings:
740 740 ui = settings.get_ui_by_section_and_key(section, key)
741 741 result_key = self._get_form_ui_key(section, key)
742 742
743 743 if ui:
744 744 if section in ('hooks', 'extensions'):
745 745 result[result_key] = ui.ui_active
746 746 elif result_key in ['vcs_git_lfs_enabled']:
747 747 result[result_key] = ui.ui_active
748 748 else:
749 749 result[result_key] = ui.ui_value
750 750
751 751 for name in self.GENERAL_SETTINGS:
752 752 setting = settings.get_setting_by_name(name)
753 753 if setting:
754 754 result_key = 'rhodecode_{}'.format(name)
755 755 result[result_key] = setting.app_settings_value
756 756
757 757 return result
758 758
759 759 def _get_form_ui_key(self, section, key):
760 760 return '{section}_{key}'.format(
761 761 section=section, key=key.replace('.', '_'))
762 762
763 763 def _create_or_update_ui(
764 764 self, settings, section, key, value=None, active=None):
765 765 ui = settings.get_ui_by_section_and_key(section, key)
766 766 if not ui:
767 767 active = True if active is None else active
768 768 settings.create_ui_section_value(
769 769 section, value, key=key, active=active)
770 770 else:
771 771 if active is not None:
772 772 ui.ui_active = active
773 773 if value is not None:
774 774 ui.ui_value = value
775 775 Session().add(ui)
776 776
777 777 def _create_svn_settings(self, settings, data):
778 778 svn_settings = {
779 779 'new_svn_branch': self.SVN_BRANCH_SECTION,
780 780 'new_svn_tag': self.SVN_TAG_SECTION
781 781 }
782 782 for key in svn_settings:
783 783 if data.get(key):
784 784 settings.create_ui_section_value(svn_settings[key], data[key])
785 785
786 786 def _create_or_update_general_settings(self, settings, data):
787 787 for name in self.GENERAL_SETTINGS:
788 788 data_key = 'rhodecode_{}'.format(name)
789 789 if data_key not in data:
790 790 raise ValueError(
791 791 'The given data does not contain {} key'.format(data_key))
792 792 setting = settings.create_or_update_setting(
793 793 name, data[data_key], 'bool')
794 794 Session().add(setting)
795 795
796 796 def _get_settings_keys(self, settings, data):
797 797 data_keys = [self._get_form_ui_key(*s) for s in settings]
798 798 for data_key in data_keys:
799 799 if data_key not in data:
800 800 raise ValueError(
801 801 'The given data does not contain {} key'.format(data_key))
802 802 return data_keys
803 803
804 804 def create_largeobjects_dirs_if_needed(self, repo_store_path):
805 805 """
806 806 This is subscribed to the `pyramid.events.ApplicationCreated` event. It
807 807 does a repository scan if enabled in the settings.
808 808 """
809 809
810 810 from rhodecode.lib.vcs.backends.hg import largefiles_store
811 811 from rhodecode.lib.vcs.backends.git import lfs_store
812 812
813 813 paths = [
814 814 largefiles_store(repo_store_path),
815 815 lfs_store(repo_store_path)]
816 816
817 817 for path in paths:
818 818 if os.path.isdir(path):
819 819 continue
820 820 if os.path.isfile(path):
821 821 continue
822 822 # not a file nor dir, we try to create it
823 823 try:
824 824 os.makedirs(path)
825 825 except Exception:
826 826 log.warning('Failed to create largefiles dir:%s', path)
General Comments 0
You need to be logged in to leave comments. Login now