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