Show More
@@ -0,0 +1,40 b'' | |||
|
1 | |RCE| 5.2.1 |RNS| | |
|
2 | ----------------- | |
|
3 | ||
|
4 | Release Date | |
|
5 | ^^^^^^^^^^^^ | |
|
6 | ||
|
7 | - 2024-09-16 | |
|
8 | ||
|
9 | ||
|
10 | New Features | |
|
11 | ^^^^^^^^^^^^ | |
|
12 | ||
|
13 | ||
|
14 | ||
|
15 | General | |
|
16 | ^^^^^^^ | |
|
17 | ||
|
18 | ||
|
19 | ||
|
20 | Security | |
|
21 | ^^^^^^^^ | |
|
22 | ||
|
23 | ||
|
24 | ||
|
25 | Performance | |
|
26 | ^^^^^^^^^^^ | |
|
27 | ||
|
28 | ||
|
29 | ||
|
30 | ||
|
31 | Fixes | |
|
32 | ^^^^^ | |
|
33 | ||
|
34 | - Fixed problems with incorrect user agent errors | |
|
35 | ||
|
36 | ||
|
37 | Upgrade notes | |
|
38 | ^^^^^^^^^^^^^ | |
|
39 | ||
|
40 | - RhodeCode 5.2.1 is unscheduled bugfix release to address some build issues with 5.2 images |
@@ -0,0 +1,45 b'' | |||
|
1 | |RCE| 5.3.0 |RNS| | |
|
2 | ----------------- | |
|
3 | ||
|
4 | Release Date | |
|
5 | ^^^^^^^^^^^^ | |
|
6 | ||
|
7 | - 2024-09-17 | |
|
8 | ||
|
9 | ||
|
10 | New Features | |
|
11 | ^^^^^^^^^^^^ | |
|
12 | ||
|
13 | - System-info: expose rhodecode config for better visibility of set settings for RhodeCode system. | |
|
14 | ||
|
15 | ||
|
16 | General | |
|
17 | ^^^^^^^ | |
|
18 | ||
|
19 | ||
|
20 | ||
|
21 | Security | |
|
22 | ^^^^^^^^ | |
|
23 | ||
|
24 | - Permissions: fixed security problem with apply-to-children from a repo group functionality breaking | |
|
25 | permissions for private repositories exposing them despite repo being private. | |
|
26 | - Git-lfs: fixed security problem with allowing off-chain attacks to replace OID data without validating hash for already present oids. | |
|
27 | This allowed to replace an LFS OID content with malicious request tailored to open RhodeCode server. | |
|
28 | ||
|
29 | ||
|
30 | Performance | |
|
31 | ^^^^^^^^^^^ | |
|
32 | ||
|
33 | ||
|
34 | ||
|
35 | ||
|
36 | Fixes | |
|
37 | ^^^^^ | |
|
38 | ||
|
39 | - Fixed problems with incorrect user agent errors | |
|
40 | ||
|
41 | ||
|
42 | Upgrade notes | |
|
43 | ^^^^^^^^^^^^^ | |
|
44 | ||
|
45 | - RhodeCode 5.3.0 is unscheduled security release to address some build issues with 5.X images |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | [bumpversion] |
|
2 |
current_version = 5. |
|
|
2 | current_version = 5.3.0 | |
|
3 | 3 | message = release: Bump version {current_version} to {new_version} |
|
4 | 4 | |
|
5 | 5 | [bumpversion:file:rhodecode/VERSION] |
@@ -71,6 +71,9 b' use = egg:rhodecode-enterprise-ce' | |||
|
71 | 71 | ; enable proxy prefix middleware, defined above |
|
72 | 72 | #filter-with = proxy-prefix |
|
73 | 73 | |
|
74 | ; control if environmental variables to be expanded into the .ini settings | |
|
75 | #rhodecode.env_expand = true | |
|
76 | ||
|
74 | 77 | ; ############# |
|
75 | 78 | ; DEBUG OPTIONS |
|
76 | 79 | ; ############# |
@@ -71,6 +71,9 b' use = egg:rhodecode-enterprise-ce' | |||
|
71 | 71 | ; enable proxy prefix middleware, defined above |
|
72 | 72 | #filter-with = proxy-prefix |
|
73 | 73 | |
|
74 | ; control if environmental variables to be expanded into the .ini settings | |
|
75 | #rhodecode.env_expand = true | |
|
76 | ||
|
74 | 77 | ; encryption key used to encrypt social plugin tokens, |
|
75 | 78 | ; remote_urls with credentials etc, if not set it defaults to |
|
76 | 79 | ; `beaker.session.secret` |
@@ -9,6 +9,8 b' Release Notes' | |||
|
9 | 9 | .. toctree:: |
|
10 | 10 | :maxdepth: 1 |
|
11 | 11 | |
|
12 | release-notes-5.3.0.rst | |
|
13 | release-notes-5.2.1.rst | |
|
12 | 14 | release-notes-5.2.0.rst |
|
13 | 15 | release-notes-5.1.2.rst |
|
14 | 16 | release-notes-5.1.1.rst |
@@ -199,8 +199,12 b' class AdminSystemInfoSettingsView(BaseAp' | |||
|
199 | 199 | |
|
200 | 200 | ] |
|
201 | 201 | |
|
202 | c.rhodecode_data_items = [ | |
|
203 | (k, v) for k, v in sorted((val('rhodecode_server_config') or {}).items(), key=lambda x: x[0].lower()) | |
|
204 | ] | |
|
205 | ||
|
202 | 206 | c.vcsserver_data_items = [ |
|
203 | (k, v) for k, v in (val('vcs_server_config') or {}).items() | |
|
207 | (k, v) for k, v in sorted((val('vcs_server_config') or {}).items(), key=lambda x: x[0].lower()) | |
|
204 | 208 | ] |
|
205 | 209 | |
|
206 | 210 | if snapshot: |
@@ -100,22 +100,16 b' class RepoSettingsPermissionsView(RepoAp' | |||
|
100 | 100 | self.load_default_context() |
|
101 | 101 | |
|
102 | 102 | private_flag = str2bool(self.request.POST.get('private')) |
|
103 | ||
|
103 | changes = { | |
|
104 | 'repo_private': private_flag | |
|
105 | } | |
|
104 | 106 | try: |
|
105 | 107 | repo = RepoModel().get(self.db_repo.repo_id) |
|
106 | repo.private = private_flag | |
|
107 | Session().add(repo) | |
|
108 | RepoModel().grant_user_permission( | |
|
109 | repo=self.db_repo, user=User.DEFAULT_USER, perm='repository.none' | |
|
110 | ) | |
|
111 | ||
|
108 | RepoModel().update(repo, **changes) | |
|
112 | 109 | Session().commit() |
|
113 | 110 | |
|
114 | 111 | h.flash(_('Repository `{}` private mode set successfully').format(self.db_repo_name), |
|
115 | 112 | category='success') |
|
116 | # NOTE(dan): we change repo private mode we need to notify all USERS | |
|
117 | affected_user_ids = User.get_all_user_ids() | |
|
118 | PermissionModel().trigger_permission_flush(affected_user_ids) | |
|
119 | 113 | |
|
120 | 114 | except Exception: |
|
121 | 115 | log.exception("Exception during update of repository") |
@@ -109,6 +109,9 b' class SettingsMaker:' | |||
|
109 | 109 | return envvar_value |
|
110 | 110 | |
|
111 | 111 | def env_expand(self): |
|
112 | if self.settings.get('rhodecode.env_expand') == 'false': | |
|
113 | return | |
|
114 | ||
|
112 | 115 | replaced = {} |
|
113 | 116 | for k, v in self.settings.items(): |
|
114 | 117 | if k not in set_keys: |
@@ -167,7 +167,8 b' def _is_request_chunked(environ):' | |||
|
167 | 167 | def _maybe_stream_request(environ): |
|
168 | 168 | path = get_path_info(environ) |
|
169 | 169 | stream = _is_request_chunked(environ) |
|
170 | log.debug('handling request `%s` with stream support: %s', path, stream) | |
|
170 | req_method = environ['REQUEST_METHOD'] | |
|
171 | log.debug('handling scm request: %s `%s` with stream support: %s', req_method, path, stream) | |
|
171 | 172 | |
|
172 | 173 | if stream: |
|
173 | 174 | # set stream by 256k |
@@ -665,6 +665,32 b' def vcs_server_config():' | |||
|
665 | 665 | |
|
666 | 666 | return SysInfoRes(value=value, state=state, human_value=human_value) |
|
667 | 667 | |
|
668 | @register_sysinfo | |
|
669 | def rhodecode_server_config(): | |
|
670 | import rhodecode | |
|
671 | ||
|
672 | state = STATE_OK_DEFAULT | |
|
673 | config = rhodecode.CONFIG.copy() | |
|
674 | ||
|
675 | secrets_lits = [ | |
|
676 | f'rhodecode_{LicenseModel.LICENSE_DB_KEY}', | |
|
677 | 'sqlalchemy.db1.url', | |
|
678 | 'channelstream.secret', | |
|
679 | 'beaker.session.secret', | |
|
680 | 'rhodecode.encrypted_values.secret', | |
|
681 | 'appenlight.api_key', | |
|
682 | 'smtp_password', | |
|
683 | 'file_store.objectstore.secret', | |
|
684 | 'archive_cache.objectstore.secret', | |
|
685 | 'app.service_api.token', | |
|
686 | ] | |
|
687 | for k in secrets_lits: | |
|
688 | if k in config: | |
|
689 | config[k] = '**OBFUSCATED**' | |
|
690 | ||
|
691 | value = human_value = config | |
|
692 | return SysInfoRes(value=value, state=state, human_value=human_value) | |
|
693 | ||
|
668 | 694 | |
|
669 | 695 | @register_sysinfo |
|
670 | 696 | def rhodecode_app_info(): |
@@ -851,6 +877,7 b' def get_system_info(environ):' | |||
|
851 | 877 | 'vcs_server': SysInfo(vcs_server)(), |
|
852 | 878 | |
|
853 | 879 | 'vcs_server_config': SysInfo(vcs_server_config)(), |
|
880 | 'rhodecode_server_config': SysInfo(rhodecode_server_config)(), | |
|
854 | 881 | |
|
855 | 882 | 'git': SysInfo(git_info)(), |
|
856 | 883 | 'hg': SysInfo(hg_info)(), |
@@ -452,15 +452,24 b' class RepoModel(BaseModel):' | |||
|
452 | 452 | |
|
453 | 453 | setattr(cur_repo, k, val) |
|
454 | 454 | |
|
455 |
new_name = |
|
|
456 |
|
|
|
455 | new_name = source_repo_name | |
|
456 | if 'repo_name' in kwargs: | |
|
457 | new_name = cur_repo.get_new_name(kwargs['repo_name']) | |
|
458 | cur_repo.repo_name = new_name | |
|
457 | 459 | |
|
458 | # if private flag is set, reset default permission to NONE | |
|
459 | if kwargs.get('repo_private'): | |
|
460 | EMPTY_PERM = 'repository.none' | |
|
461 | RepoModel().grant_user_permission( | |
|
462 | repo=cur_repo, user=User.DEFAULT_USER, perm=EMPTY_PERM | |
|
463 | ) | |
|
460 | if 'repo_private' in kwargs: | |
|
461 | # if private flag is set to True, reset default permission to NONE | |
|
462 | set_private_to = kwargs.get('repo_private') | |
|
463 | if set_private_to: | |
|
464 | EMPTY_PERM = 'repository.none' | |
|
465 | RepoModel().grant_user_permission( | |
|
466 | repo=cur_repo, user=User.DEFAULT_USER, perm=EMPTY_PERM | |
|
467 | ) | |
|
468 | if set_private_to != cur_repo.private: | |
|
469 | # NOTE(dan): we change repo private mode we need to notify all USERS | |
|
470 | # this is just by having this value set to a different value then it was before | |
|
471 | affected_user_ids = User.get_all_user_ids() | |
|
472 | ||
|
464 | 473 | if kwargs.get('repo_landing_rev'): |
|
465 | 474 | landing_rev_val = kwargs['repo_landing_rev'] |
|
466 | 475 | RepoModel().set_landing_rev(cur_repo, landing_rev_val) |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2011-202 |
|
|
1 | # Copyright (C) 2011-2024 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -30,7 +30,6 b' import time' | |||
|
30 | 30 | import traceback |
|
31 | 31 | import string |
|
32 | 32 | |
|
33 | from zope.cachedescriptors.property import Lazy as LazyProperty | |
|
34 | 33 | |
|
35 | 34 | from rhodecode import events |
|
36 | 35 | from rhodecode.model import BaseModel |
@@ -38,7 +37,7 b' from rhodecode.model.db import (_hash_ke' | |||
|
38 | 37 | Session, RepoGroup, UserRepoGroupToPerm, User, Permission, UserGroupRepoGroupToPerm, |
|
39 | 38 | UserGroup, Repository) |
|
40 | 39 | from rhodecode.model.permission import PermissionModel |
|
41 |
from rhodecode.model.settings import |
|
|
40 | from rhodecode.model.settings import SettingsModel | |
|
42 | 41 | from rhodecode.lib.caching_query import FromCache |
|
43 | 42 | from rhodecode.lib.utils2 import action_logger_generic |
|
44 | 43 | |
@@ -350,46 +349,45 b' class RepoGroupModel(BaseModel):' | |||
|
350 | 349 | 'default_user_changed': None |
|
351 | 350 | } |
|
352 | 351 | |
|
353 | def _set_perm_user(obj, user, perm): | |
|
354 | if isinstance(obj, RepoGroup): | |
|
355 | self.grant_user_permission( | |
|
356 |
|
|
|
357 | elif isinstance(obj, Repository): | |
|
352 | def _set_perm_user(_obj: RepoGroup | Repository, _user_obj: User, _perm): | |
|
353 | ||
|
354 | if isinstance(_obj, RepoGroup): | |
|
355 | self.grant_user_permission(repo_group=_obj, user=_user_obj, perm=_perm) | |
|
356 | elif isinstance(_obj, Repository): | |
|
358 | 357 | # private repos will not allow to change the default |
|
359 | 358 | # permissions using recursive mode |
|
360 | if obj.private and user == User.DEFAULT_USER: | |
|
359 | if _obj.private and _user_obj.username == User.DEFAULT_USER: | |
|
360 | log.debug('Skipping private repo %s for user %s', _obj, _user_obj) | |
|
361 | 361 | return |
|
362 | 362 | |
|
363 |
# we set group permission |
|
|
364 | # permission | |
|
365 | perm = perm.replace('group.', 'repository.') | |
|
366 | RepoModel().grant_user_permission( | |
|
367 | repo=obj, user=user, perm=perm) | |
|
363 | # we set group permission, we have to switch to repo permission definition | |
|
364 | new_perm = _perm.replace('group.', 'repository.') | |
|
365 | RepoModel().grant_user_permission(repo=_obj, user=_user_obj, perm=new_perm) | |
|
366 | ||
|
367 | def _set_perm_group(_obj: RepoGroup | Repository, users_group: UserGroup, _perm): | |
|
368 | if isinstance(_obj, RepoGroup): | |
|
369 | self.grant_user_group_permission(repo_group=_obj, group_name=users_group, perm=_perm) | |
|
370 | elif isinstance(_obj, Repository): | |
|
371 | # we set group permission, we have to switch to repo permission definition | |
|
372 | new_perm = _perm.replace('group.', 'repository.') | |
|
373 | RepoModel().grant_user_group_permission(repo=_obj, group_name=users_group, perm=new_perm) | |
|
368 | 374 | |
|
369 | def _set_perm_group(obj, users_group, perm): | |
|
370 | if isinstance(obj, RepoGroup): | |
|
371 |
self. |
|
|
372 | repo_group=obj, group_name=users_group, perm=perm) | |
|
373 | elif isinstance(obj, Repository): | |
|
374 | # we set group permission but we have to switch to repo | |
|
375 | # permission | |
|
376 | perm = perm.replace('group.', 'repository.') | |
|
377 | RepoModel().grant_user_group_permission( | |
|
378 | repo=obj, group_name=users_group, perm=perm) | |
|
375 | def _revoke_perm_user(_obj: RepoGroup | Repository, _user_obj: User): | |
|
376 | if isinstance(_obj, RepoGroup): | |
|
377 | self.revoke_user_permission(repo_group=_obj, user=_user_obj) | |
|
378 | elif isinstance(_obj, Repository): | |
|
379 | # private repos will not allow to change the default | |
|
380 | # permissions using recursive mode, also there's no revocation fo default user, just update | |
|
381 | if _user_obj.username == User.DEFAULT_USER: | |
|
382 | log.debug('Skipping private repo %s for user %s', _obj, _user_obj) | |
|
383 | return | |
|
384 | RepoModel().revoke_user_permission(repo=_obj, user=_user_obj) | |
|
379 | 385 | |
|
380 |
def _revoke_perm_ |
|
|
381 | if isinstance(obj, RepoGroup): | |
|
382 |
self.revoke_user_permission(repo_group=obj, |
|
|
383 | elif isinstance(obj, Repository): | |
|
384 |
RepoModel().revoke_user_permission(repo=obj, |
|
|
385 | ||
|
386 | def _revoke_perm_group(obj, user_group): | |
|
387 | if isinstance(obj, RepoGroup): | |
|
388 | self.revoke_user_group_permission( | |
|
389 | repo_group=obj, group_name=user_group) | |
|
390 | elif isinstance(obj, Repository): | |
|
391 | RepoModel().revoke_user_group_permission( | |
|
392 | repo=obj, group_name=user_group) | |
|
386 | def _revoke_perm_group(_obj: RepoGroup | Repository, user_group: UserGroup): | |
|
387 | if isinstance(_obj, RepoGroup): | |
|
388 | self.revoke_user_group_permission(repo_group=_obj, group_name=user_group) | |
|
389 | elif isinstance(_obj, Repository): | |
|
390 | RepoModel().revoke_user_group_permission(repo=_obj, group_name=user_group) | |
|
393 | 391 | |
|
394 | 392 | # start updates |
|
395 | 393 | log.debug('Now updating permissions for %s in recursive mode:%s', |
@@ -423,7 +421,8 b' class RepoGroupModel(BaseModel):' | |||
|
423 | 421 | for member_id, perm, member_type in perm_updates: |
|
424 | 422 | member_id = int(member_id) |
|
425 | 423 | if member_type == 'user': |
|
426 |
member_ |
|
|
424 | member_obj = User.get(member_id) | |
|
425 | member_name = member_obj.username | |
|
427 | 426 | if isinstance(obj, RepoGroup) and obj == repo_group and member_name == User.DEFAULT_USER: |
|
428 | 427 | # NOTE(dan): detect if we changed permissions for default user |
|
429 | 428 | perm_obj = self.sa.query(UserRepoGroupToPerm) \ |
@@ -434,15 +433,16 b' class RepoGroupModel(BaseModel):' | |||
|
434 | 433 | changes['default_user_changed'] = True |
|
435 | 434 | |
|
436 | 435 | # this updates also current one if found |
|
437 |
_set_perm_user(obj, |
|
|
436 | _set_perm_user(obj, member_obj, perm) | |
|
438 | 437 | elif member_type == 'user_group': |
|
439 |
member_ |
|
|
440 | if not check_perms or has_group_perm(member_name, | |
|
441 | user=cur_user): | |
|
442 |
_set_perm_group(obj, |
|
|
438 | member_obj = UserGroup.get(member_id) | |
|
439 | member_name = member_obj.users_group_name | |
|
440 | if not check_perms or has_group_perm(member_name, user=cur_user): | |
|
441 | _set_perm_group(obj, member_obj, perm) | |
|
443 | 442 | else: |
|
444 |
raise ValueError( |
|
|
445 | "got {} instead".format(member_type)) | |
|
443 | raise ValueError( | |
|
444 | f"member_type must be 'user' or 'user_group' got {member_type} instead" | |
|
445 | ) | |
|
446 | 446 | |
|
447 | 447 | changes['updated'].append( |
|
448 | 448 | {'change_obj': change_obj, 'type': member_type, |
@@ -452,17 +452,19 b' class RepoGroupModel(BaseModel):' | |||
|
452 | 452 | for member_id, perm, member_type in perm_additions: |
|
453 | 453 | member_id = int(member_id) |
|
454 | 454 | if member_type == 'user': |
|
455 |
member_ |
|
|
456 | _set_perm_user(obj, user=member_id, perm=perm) | |
|
455 | member_obj = User.get(member_id) | |
|
456 | member_name = member_obj.username | |
|
457 | _set_perm_user(obj, member_obj, perm) | |
|
457 | 458 | elif member_type == 'user_group': |
|
458 | 459 | # check if we have permissions to alter this usergroup |
|
459 |
member_ |
|
|
460 | if not check_perms or has_group_perm(member_name, | |
|
461 | user=cur_user): | |
|
462 |
_set_perm_group(obj, |
|
|
460 | member_obj = UserGroup.get(member_id) | |
|
461 | member_name = member_obj.users_group_name | |
|
462 | if not check_perms or has_group_perm(member_name, user=cur_user): | |
|
463 | _set_perm_group(obj, member_obj, perm) | |
|
463 | 464 | else: |
|
464 |
raise ValueError( |
|
|
465 | "got {} instead".format(member_type)) | |
|
465 | raise ValueError( | |
|
466 | f"member_type must be 'user' or 'user_group' got {member_type} instead" | |
|
467 | ) | |
|
466 | 468 | |
|
467 | 469 | changes['added'].append( |
|
468 | 470 | {'change_obj': change_obj, 'type': member_type, |
@@ -472,18 +474,19 b' class RepoGroupModel(BaseModel):' | |||
|
472 | 474 | for member_id, perm, member_type in perm_deletions: |
|
473 | 475 | member_id = int(member_id) |
|
474 | 476 | if member_type == 'user': |
|
475 |
member_ |
|
|
476 | _revoke_perm_user(obj, user=member_id) | |
|
477 | member_obj = User.get(member_id) | |
|
478 | member_name = member_obj.username | |
|
479 | _revoke_perm_user(obj, member_obj) | |
|
477 | 480 | elif member_type == 'user_group': |
|
478 | 481 | # check if we have permissions to alter this usergroup |
|
479 |
member_ |
|
|
480 | if not check_perms or has_group_perm(member_name, | |
|
481 | user=cur_user): | |
|
482 |
_revoke_perm_group(obj, |
|
|
482 | member_obj = UserGroup.get(member_id) | |
|
483 | member_name = member_obj.users_group_name | |
|
484 | if not check_perms or has_group_perm(member_name, user=cur_user): | |
|
485 | _revoke_perm_group(obj, member_obj) | |
|
483 | 486 | else: |
|
484 |
raise ValueError( |
|
|
485 | "got {} instead".format(member_type)) | |
|
486 | ||
|
487 | raise ValueError( | |
|
488 | f"member_type must be 'user' or 'user_group' got {member_type} instead" | |
|
489 | ) | |
|
487 | 490 | changes['deleted'].append( |
|
488 | 491 | {'change_obj': change_obj, 'type': member_type, |
|
489 | 492 | 'id': member_id, 'name': member_name, 'new_perm': perm}) |
@@ -42,7 +42,7 b' class UpdateModel(BaseModel):' | |||
|
42 | 42 | ver = rhodecode.__version__ |
|
43 | 43 | log.debug('Checking for upgrade on `%s` server', update_url) |
|
44 | 44 | opener = urllib.request.build_opener() |
|
45 |
opener.addheaders = [('User-agent', 'RhodeCode-SCM/ |
|
|
45 | opener.addheaders = [('User-agent', f'RhodeCode-SCM/{ver.strip()}')] | |
|
46 | 46 | response = opener.open(update_url) |
|
47 | 47 | response_data = response.read() |
|
48 | 48 | data = json.loads(response_data) |
@@ -29,7 +29,21 b'' | |||
|
29 | 29 | |
|
30 | 30 | <div class="panel panel-default"> |
|
31 | 31 | <div class="panel-heading"> |
|
32 |
<h3 class="panel-title">${_(' |
|
|
32 | <h3 class="panel-title">${_('RhodeCode Server Config')}</h3> | |
|
33 | </div> | |
|
34 | <div class="panel-body"> | |
|
35 | <dl class="dl-horizontal settings dt-400"> | |
|
36 | % for dt, dd in c.rhodecode_data_items: | |
|
37 | <dt>${dt}${':' if dt else '---'}</dt> | |
|
38 | <dd>${dd}${'' if dt else '---'}</dd> | |
|
39 | % endfor | |
|
40 | </dl> | |
|
41 | </div> | |
|
42 | </div> | |
|
43 | ||
|
44 | <div class="panel panel-default"> | |
|
45 | <div class="panel-heading"> | |
|
46 | <h3 class="panel-title">${_('VCS Server Config')}</h3> | |
|
33 | 47 | </div> |
|
34 | 48 | <div class="panel-body"> |
|
35 | 49 | <dl class="dl-horizontal settings dt-400"> |
@@ -166,6 +166,74 b' class TestPermissions(object):' | |||
|
166 | 166 | |
|
167 | 167 | test_user_group.user = org_owner |
|
168 | 168 | |
|
169 | def test_propagated_permissions_from_repo_group_to_private_repo(self, repo_name): | |
|
170 | # make group | |
|
171 | self.g1 = fixture.create_repo_group('TOP_LEVEL', skip_if_exists=True) | |
|
172 | # both perms should be read ! | |
|
173 | assert group_perms(self.anon) == { | |
|
174 | 'TOP_LEVEL': 'group.read' | |
|
175 | } | |
|
176 | ||
|
177 | # Create repo inside the TOP_LEVEL | |
|
178 | repo_name_in_group = RepoGroup.url_sep().join([self.g1.group_name, 'test_perm_on_private_repo']) | |
|
179 | self.test_repo = fixture.create_repo(name=repo_name_in_group, | |
|
180 | repo_type='hg', | |
|
181 | repo_group=self.g1, | |
|
182 | cur_user=self.u1,) | |
|
183 | assert repo_perms(self.anon) == { | |
|
184 | repo_name_in_group: 'repository.read', | |
|
185 | 'vcs_test_git': 'repository.read', | |
|
186 | 'vcs_test_hg': 'repository.read', | |
|
187 | 'vcs_test_svn': 'repository.read', | |
|
188 | } | |
|
189 | # Now change default user permissions | |
|
190 | new_perm = 'repository.write' | |
|
191 | perm_updates = [ | |
|
192 | [self.anon.user_id, new_perm, 'user'] | |
|
193 | ] | |
|
194 | RepoGroupModel().update_permissions( | |
|
195 | repo_group=self.g1, perm_updates=perm_updates, recursive='all') | |
|
196 | ||
|
197 | Session().commit() | |
|
198 | assert repo_perms(self.anon) == { | |
|
199 | repo_name_in_group: new_perm, | |
|
200 | 'vcs_test_git': 'repository.read', | |
|
201 | 'vcs_test_hg': 'repository.read', | |
|
202 | 'vcs_test_svn': 'repository.read', | |
|
203 | } | |
|
204 | ||
|
205 | # NOW MARK repo as private | |
|
206 | changes = { | |
|
207 | 'repo_private': True | |
|
208 | } | |
|
209 | repo = RepoModel().get_by_repo_name(repo_name_in_group) | |
|
210 | RepoModel().update(repo, **changes) | |
|
211 | Session().commit() | |
|
212 | ||
|
213 | # Private repo sets 'none' permission for default user | |
|
214 | assert repo_perms(self.anon) == { | |
|
215 | repo_name_in_group: 'repository.none', | |
|
216 | 'vcs_test_git': 'repository.read', | |
|
217 | 'vcs_test_hg': 'repository.read', | |
|
218 | 'vcs_test_svn': 'repository.read', | |
|
219 | } | |
|
220 | ||
|
221 | # apply same logic of "updated" recursive, but now the anon permissions should be not be impacted | |
|
222 | new_perm = 'repository.write' | |
|
223 | perm_updates = [ | |
|
224 | [self.anon.user_id, new_perm, 'user'] | |
|
225 | ] | |
|
226 | RepoGroupModel().update_permissions( | |
|
227 | repo_group=self.g1, perm_updates=perm_updates, recursive='all') | |
|
228 | ||
|
229 | Session().commit() | |
|
230 | assert repo_perms(self.anon) == { | |
|
231 | repo_name_in_group: 'repository.none', | |
|
232 | 'vcs_test_git': 'repository.read', | |
|
233 | 'vcs_test_hg': 'repository.read', | |
|
234 | 'vcs_test_svn': 'repository.read', | |
|
235 | } | |
|
236 | ||
|
169 | 237 | def test_propagated_permission_from_users_group_by_explicit_perms_exist( |
|
170 | 238 | self, repo_name): |
|
171 | 239 | # make group |
@@ -71,6 +71,9 b' use = egg:rhodecode-enterprise-ce' | |||
|
71 | 71 | ; enable proxy prefix middleware, defined above |
|
72 | 72 | #filter-with = proxy-prefix |
|
73 | 73 | |
|
74 | ; control if environmental variables to be expanded into the .ini settings | |
|
75 | rhodecode.env_expand = false | |
|
76 | ||
|
74 | 77 | ; encryption key used to encrypt social plugin tokens, |
|
75 | 78 | ; remote_urls with credentials etc, if not set it defaults to |
|
76 | 79 | ; `beaker.session.secret` |
@@ -225,6 +228,13 b' license_token = abra-cada-bra1-rce3' | |||
|
225 | 228 | ; This flag hides sensitive information on the license page such as token, and license data |
|
226 | 229 | license.hide_license_info = false |
|
227 | 230 | |
|
231 | ; Import EE license from this license path | |
|
232 | #license.import_path = %(here)s/rhodecode_enterprise.license | |
|
233 | ||
|
234 | ; import license 'if-missing' or 'force' (always override) | |
|
235 | ; if-missing means apply license if it doesn't exist. 'force' option always overrides it | |
|
236 | license.import_path_mode = if-missing | |
|
237 | ||
|
228 | 238 | ; supervisor connection uri, for managing supervisor and logs. |
|
229 | 239 | supervisor.uri = |
|
230 | 240 | |
@@ -658,6 +668,12 b' vcs.connection_timeout = 3600' | |||
|
658 | 668 | ; It uses cache_region `cache_repo` |
|
659 | 669 | vcs.methods.cache = false |
|
660 | 670 | |
|
671 | ; Filesystem location where Git lfs objects should be stored | |
|
672 | vcs.git.lfs.storage_location = /var/opt/rhodecode_repo_store/.cache/git_lfs_store | |
|
673 | ||
|
674 | ; Filesystem location where Mercurial largefile objects should be stored | |
|
675 | vcs.hg.largefiles.storage_location = /var/opt/rhodecode_repo_store/.cache/hg_largefiles_store | |
|
676 | ||
|
661 | 677 | ; #################################################### |
|
662 | 678 | ; Subversion proxy support (mod_dav_svn) |
|
663 | 679 | ; Maps RhodeCode repo groups into SVN paths for Apache |
General Comments 0
You need to be logged in to leave comments.
Login now