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