From e1580f8dd96a701248ca6dffd8590b9703561713 Mon Sep 17 00:00:00 2001 From: Marcin Kuzminski Date: Tue, 16 Jul 2019 11:42:56 +0200 Subject: [PATCH 01/23] rcextensions: improved messaging on rcextensions load fail --- rhodecode/lib/utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rhodecode/lib/utils.py b/rhodecode/lib/utils.py index 5c9051f9..ef480031 100644 --- a/rhodecode/lib/utils.py +++ b/rhodecode/lib/utils.py @@ -634,10 +634,12 @@ def load_rcextensions(root_path): path = os.path.join(root_path) sys.path.append(path) + try: rcextensions = __import__('rcextensions') except ImportError: - log.warn('Unable to load rcextensions from %s', path) + if os.path.isdir(os.path.join(path, 'rcextensions')): + log.warn('Unable to load rcextensions from %s', path) rcextensions = None if rcextensions: From 61cc082f782b137e814ce89c932e209fe141ecb3 Mon Sep 17 00:00:00 2001 From: Marcin Kuzminski Date: Thu, 18 Jul 2019 15:56:53 +0200 Subject: [PATCH 02/23] config: fixed special character in gunicorn config. --- configs/gunicorn_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/gunicorn_config.py b/configs/gunicorn_config.py index 89c54976..89e5ab11 100644 --- a/configs/gunicorn_config.py +++ b/configs/gunicorn_config.py @@ -34,7 +34,7 @@ loglevel = 'debug' limit_request_line = 0 # Limit the number of HTTP headers fields in a request. -# By default this value is 100 and can’t be larger than 32768. +# By default this value is 100 and can't be larger than 32768. limit_request_fields = 10240 # Limit the allowed size of an HTTP request header field. From 32a4059a75c7f83d9dd1863c6643a4189f9c8890 Mon Sep 17 00:00:00 2001 From: Daniel Dourvaris Date: Tue, 23 Jul 2019 14:25:33 +0200 Subject: [PATCH 03/23] pull-requests: add indication of state change in list of pull-requests and actually show them in the list. --- rhodecode/apps/my_account/views/my_account.py | 4 ++-- rhodecode/apps/repository/views/repo_pull_requests.py | 4 ++-- rhodecode/model/pull_request.py | 2 +- rhodecode/public/css/main.less | 10 +++++++++- .../admin/my_account/my_account_pullrequests.mako | 3 +++ rhodecode/templates/pullrequests/pullrequests.mako | 5 ++++- 6 files changed, 21 insertions(+), 7 deletions(-) diff --git a/rhodecode/apps/my_account/views/my_account.py b/rhodecode/apps/my_account/views/my_account.py index 2d4fa4f4..c8bdbaa5 100644 --- a/rhodecode/apps/my_account/views/my_account.py +++ b/rhodecode/apps/my_account/views/my_account.py @@ -669,8 +669,7 @@ class MyAccountView(BaseAppView, DataGridAppView): 'name_raw': pr.pull_request_id, 'status': _render('pullrequest_status', pr.calculated_review_status()), - 'title': _render( - 'pullrequest_title', pr.title, pr.description), + 'title': _render('pullrequest_title', pr.title, pr.description), 'description': h.escape(pr.description), 'updated_on': _render('pullrequest_updated_on', h.datetime_to_time(pr.updated_on)), @@ -678,6 +677,7 @@ class MyAccountView(BaseAppView, DataGridAppView): 'created_on': _render('pullrequest_updated_on', h.datetime_to_time(pr.created_on)), 'created_on_raw': h.datetime_to_time(pr.created_on), + 'state': pr.pull_request_state, 'author': _render('pullrequest_author', pr.author.full_contact, ), 'author_raw': pr.author.full_name, diff --git a/rhodecode/apps/repository/views/repo_pull_requests.py b/rhodecode/apps/repository/views/repo_pull_requests.py index 0dac0610..e8a1a88d 100644 --- a/rhodecode/apps/repository/views/repo_pull_requests.py +++ b/rhodecode/apps/repository/views/repo_pull_requests.py @@ -112,8 +112,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): 'name_raw': pr.pull_request_id, 'status': _render('pullrequest_status', pr.calculated_review_status()), - 'title': _render( - 'pullrequest_title', pr.title, pr.description), + 'title': _render('pullrequest_title', pr.title, pr.description), 'description': h.escape(pr.description), 'updated_on': _render('pullrequest_updated_on', h.datetime_to_time(pr.updated_on)), @@ -121,6 +120,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): 'created_on': _render('pullrequest_updated_on', h.datetime_to_time(pr.created_on)), 'created_on_raw': h.datetime_to_time(pr.created_on), + 'state': pr.pull_request_state, 'author': _render('pullrequest_author', pr.author.full_contact, ), 'author_raw': pr.author.full_name, diff --git a/rhodecode/model/pull_request.py b/rhodecode/model/pull_request.py index 848eb7a2..cac7c69e 100644 --- a/rhodecode/model/pull_request.py +++ b/rhodecode/model/pull_request.py @@ -139,7 +139,7 @@ class PullRequestModel(BaseModel): def _prepare_get_all_query(self, repo_name, source=False, statuses=None, opened_by=None, order_by=None, - order_dir='desc', only_created=True): + order_dir='desc', only_created=False): repo = None if repo_name: repo = self._get_repo(repo_name) diff --git a/rhodecode/public/css/main.less b/rhodecode/public/css/main.less index c3697fed..e625d2f6 100644 --- a/rhodecode/public/css/main.less +++ b/rhodecode/public/css/main.less @@ -333,10 +333,18 @@ ul.auth_plugins { margin: 0 1em 0 0; } -.pullrequestlist { +#pull_request_list_table { .closed { background-color: @grey6; } + + .state-creating, + .state-updating, + .state-merging + { + background-color: @grey6; + } + .td-status { padding-left: .5em; } diff --git a/rhodecode/templates/admin/my_account/my_account_pullrequests.mako b/rhodecode/templates/admin/my_account/my_account_pullrequests.mako index da60a5be..c33da5ae 100644 --- a/rhodecode/templates/admin/my_account/my_account_pullrequests.mako +++ b/rhodecode/templates/admin/my_account/my_account_pullrequests.mako @@ -77,6 +77,9 @@ $(document).ready(function() { if (data['owned']) { $(row).addClass('owned'); } + if (data['state'] !== 'created') { + $(row).addClass('state-' + data['state']); + } } }); $pullRequestListTable.on('xhr.dt', function(e, settings, json, xhr){ diff --git a/rhodecode/templates/pullrequests/pullrequests.mako b/rhodecode/templates/pullrequests/pullrequests.mako index 71183e78..d9fe95ea 100644 --- a/rhodecode/templates/pullrequests/pullrequests.mako +++ b/rhodecode/templates/pullrequests/pullrequests.mako @@ -98,7 +98,10 @@ $(document).ready(function() { }, "createdRow": function ( row, data, index ) { if (data['closed']) { - $(row).addClass('closed'); + $(row).addClass('closed'); + } + if (data['state'] !== 'created') { + $(row).addClass('state-' + data['state']); } } }); From ea4327217137d65077566a38ddb1de2c4cb68dc5 Mon Sep 17 00:00:00 2001 From: Marcin Kuzminski Date: Wed, 24 Jul 2019 11:53:06 +0200 Subject: [PATCH 04/23] path-filter: enable for quick search menu. --- rhodecode/apps/_base/__init__.py | 12 +++++++++--- rhodecode/apps/repository/views/repo_files.py | 4 +++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/rhodecode/apps/_base/__init__.py b/rhodecode/apps/_base/__init__.py index 2d8c0833..4fe4fffb 100644 --- a/rhodecode/apps/_base/__init__.py +++ b/rhodecode/apps/_base/__init__.py @@ -320,9 +320,15 @@ class PathFilter(object): self.permission_checker = permission_checker def assert_path_permissions(self, path): - if path and self.permission_checker and not self.permission_checker.has_access(path): - raise HTTPForbidden() - return path + if self.path_access_allowed(path): + return path + raise HTTPForbidden() + + def path_access_allowed(self, path): + log.debug('Checking ACL permissions for PathFilter for `%s`', path) + if self.permission_checker: + return path and self.permission_checker.has_access(path) + return True def filter_patchset(self, patchset): if not self.permission_checker or not patchset: diff --git a/rhodecode/apps/repository/views/repo_files.py b/rhodecode/apps/repository/views/repo_files.py index 638014e1..a69ed758 100644 --- a/rhodecode/apps/repository/views/repo_files.py +++ b/rhodecode/apps/repository/views/repo_files.py @@ -904,9 +904,11 @@ class RepoFilesView(RepoAppView): raise HTTPFound(h.route_path( 'repo_files', repo_name=self.db_repo_name, commit_id='tip', f_path='/')) + return _d + _f - return compute_file_search(self.db_repo.repo_id, commit_id, f_path) + result = compute_file_search(self.db_repo.repo_id, commit_id, f_path) + return filter(lambda n: self.path_filter.path_access_allowed(n['name']), result) @LoginRequired() @HasRepoPermissionAnyDecorator( From 7aa754bea515d611371993d99e4e0046e32c2da8 Mon Sep 17 00:00:00 2001 From: Marcin Kuzminski Date: Thu, 25 Jul 2019 21:52:14 +0200 Subject: [PATCH 05/23] pull-requests: make merge state default as False. This causes a lot of performance problems and should default to faster way --- rhodecode/api/views/pull_request_api.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/rhodecode/api/views/pull_request_api.py b/rhodecode/api/views/pull_request_api.py index 7faccd2b..a0e6a86e 100644 --- a/rhodecode/api/views/pull_request_api.py +++ b/rhodecode/api/views/pull_request_api.py @@ -43,7 +43,8 @@ log = logging.getLogger(__name__) @jsonrpc_method() -def get_pull_request(request, apiuser, pullrequestid, repoid=Optional(None)): +def get_pull_request(request, apiuser, pullrequestid, repoid=Optional(None), + merge_state=Optional(False)): """ Get a pull request based on the given ID. @@ -54,6 +55,9 @@ def get_pull_request(request, apiuser, pullrequestid, repoid=Optional(None)): :type repoid: str or int :param pullrequestid: ID of the requested pull request. :type pullrequestid: int + :param merge_state: Optional calculate merge state for each repository. + This could result in longer time to fetch the data + :type merge_state: bool Example output: @@ -135,14 +139,15 @@ def get_pull_request(request, apiuser, pullrequestid, repoid=Optional(None)): # NOTE(marcink): only calculate and return merge state if the pr state is 'created' # otherwise we can lock the repo on calculation of merge state while update/merge # is happening. - merge_state = pull_request.pull_request_state == pull_request.STATE_CREATED + pr_created = pull_request.pull_request_state == pull_request.STATE_CREATED + merge_state = Optional.extract(merge_state, binary=True) and pr_created data = pull_request.get_api_data(with_merge_state=merge_state) return data @jsonrpc_method() def get_pull_requests(request, apiuser, repoid, status=Optional('new'), - merge_state=Optional(True)): + merge_state=Optional(False)): """ Get all pull requests from the repository specified in `repoid`. From ce94cefb173254e19887b9f25ee4154ad4d3a3af Mon Sep 17 00:00:00 2001 From: Marcin Kuzminski Date: Thu, 25 Jul 2019 22:02:35 +0200 Subject: [PATCH 06/23] docs: added 4.17.3 release notes --- docs/release-notes/release-notes-4.17.3.rst | 58 +++++++++++++++++++++ docs/release-notes/release-notes.rst | 1 + 2 files changed, 59 insertions(+) create mode 100644 docs/release-notes/release-notes-4.17.3.rst diff --git a/docs/release-notes/release-notes-4.17.3.rst b/docs/release-notes/release-notes-4.17.3.rst new file mode 100644 index 00000000..6e1ef061 --- /dev/null +++ b/docs/release-notes/release-notes-4.17.3.rst @@ -0,0 +1,58 @@ +|RCE| 4.17.3 |RNS| +------------------ + +Release Date +^^^^^^^^^^^^ + +- 2019-07-25 + + +New Features +^^^^^^^^^^^^ + + + +General +^^^^^^^ + +- RSS: use permalinks without slashes for feeds. Fixes #5557. RSS feed will now use + links that won't change when a repository is renamed, and in addition they now have + better compatibility with Outlook. +- Pull Requests: make merge state calculation default to disabled. + This causes a lot of performance problems and should default to faster way +- Pull Requests: add indication of state change in list of pull-requests and actually + show them in the list. Before PRs that were in states like "merging" were hidden from + the PR list. Now we show them with grey-out display indicating PR is changing states. +- API: extended upload api to be able to upload files with ACL checks enabled + + +Security +^^^^^^^^ + + + +Performance +^^^^^^^^^^^ + +- Pull Requests: don't calculate merge state several times for repo on each pr display object state. +- Logging: http logging should limit the data to some sane amount. + In some cases we could log 100MBs into logs that weren't useful at all. + + +Fixes +^^^^^ + +- config: fixed special character in gunicorn config that caused problems during installation. +- path-filter: enable checking for files access for quick search menu in files view. +- rcextensions: improved messaging on rcextensions load fail +- Repository permissions: enable shortcut to set private mode in permission page. +- UI: fixed style for ancestor commit. Fixes #5558 +- Events: ensure stable execution of integrations (in order: global, per-group, per-repo) +- Settings: custom header/footer code message correction +- Artifacts: don't crash when metadata isn't complete. This can be a case for edited upload attachements + + +Upgrade notes +^^^^^^^^^^^^^ + +- Scheduled release addressing problems in 4.17.X releases. diff --git a/docs/release-notes/release-notes.rst b/docs/release-notes/release-notes.rst index 0891407b..1267d5b5 100644 --- a/docs/release-notes/release-notes.rst +++ b/docs/release-notes/release-notes.rst @@ -9,6 +9,7 @@ Release Notes .. toctree:: :maxdepth: 1 + release-notes-4.17.3.rst release-notes-4.17.2.rst release-notes-4.17.1.rst release-notes-4.17.0.rst From 2e2cc3162d13f5f34b0ea976e284cad0dfcccdb7 Mon Sep 17 00:00:00 2001 From: Marcin Kuzminski Date: Thu, 25 Jul 2019 20:08:16 +0000 Subject: [PATCH 07/23] release: Start preparation for 4.17.3 --- .bumpversion.cfg | 2 +- .release.cfg | 9 ++------- rhodecode/VERSION | 2 +- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 5b2583c5..1ad974af 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 4.17.2 +current_version = 4.17.3 message = release: Bump version {current_version} to {new_version} [bumpversion:file:rhodecode/VERSION] diff --git a/.release.cfg b/.release.cfg index 7b69b1a2..8298c027 100644 --- a/.release.cfg +++ b/.release.cfg @@ -5,23 +5,18 @@ done = false done = true [task:rc_tools_pinned] -done = true [task:fixes_on_stable] -done = true [task:pip2nix_generated] -done = true [task:changelog_updated] -done = true [task:generate_api_docs] -done = true [release] -state = prepared -version = 4.17.2 +state = in_progress +version = 4.17.3 [task:updated_translation] diff --git a/rhodecode/VERSION b/rhodecode/VERSION index 7ef918f3..a52013d9 100644 --- a/rhodecode/VERSION +++ b/rhodecode/VERSION @@ -1 +1 @@ -4.17.2 \ No newline at end of file +4.17.3 \ No newline at end of file From 934cd51cc5d94b27fe7ef1264adea438d55dfc2d Mon Sep 17 00:00:00 2001 From: Marcin Kuzminski Date: Thu, 25 Jul 2019 20:14:48 +0000 Subject: [PATCH 08/23] release: updated pip2nix output for 4.17.3 --- .release.cfg | 4 ++++ pkgs/python-packages.nix | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.release.cfg b/.release.cfg index 8298c027..95a370d4 100644 --- a/.release.cfg +++ b/.release.cfg @@ -5,14 +5,18 @@ done = false done = true [task:rc_tools_pinned] +done = true [task:fixes_on_stable] +done = true [task:pip2nix_generated] [task:changelog_updated] +done = true [task:generate_api_docs] +done = true [release] state = in_progress diff --git a/pkgs/python-packages.nix b/pkgs/python-packages.nix index 36aa4c73..e562b201 100644 --- a/pkgs/python-packages.nix +++ b/pkgs/python-packages.nix @@ -1718,7 +1718,7 @@ self: super: { }; }; "rhodecode-enterprise-ce" = super.buildPythonPackage { - name = "rhodecode-enterprise-ce-4.17.2"; + name = "rhodecode-enterprise-ce-4.17.3"; buildInputs = [ self."pytest" self."py" From d3dc3d7dedb66d68836afba94f22b1c24cd0b4fa Mon Sep 17 00:00:00 2001 From: Marcin Kuzminski Date: Thu, 25 Jul 2019 20:14:51 +0000 Subject: [PATCH 09/23] release: Finish preparation for 4.17.3 --- .release.cfg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.release.cfg b/.release.cfg index 95a370d4..181be05b 100644 --- a/.release.cfg +++ b/.release.cfg @@ -11,6 +11,7 @@ done = true done = true [task:pip2nix_generated] +done = true [task:changelog_updated] done = true @@ -19,7 +20,7 @@ done = true done = true [release] -state = in_progress +state = prepared version = 4.17.3 [task:updated_translation] From 2b68630d14ed1d7e8efcaf0a62534f6fd094808a Mon Sep 17 00:00:00 2001 From: Marcin Kuzminski Date: Thu, 25 Jul 2019 20:14:52 +0000 Subject: [PATCH 10/23] Added tag v4.17.3 for changeset 037f5794b55a From 819ebd07272eea6a74628042c8ec09e6d5107229 Mon Sep 17 00:00:00 2001 From: Marcin Kuzminski Date: Tue, 20 Aug 2019 10:48:36 +0200 Subject: [PATCH 11/23] permissions: properly flush user cache permissions in more cases of permission changes. - fixed #5560 --- rhodecode/api/views/repo_api.py | 13 +++++++++---- rhodecode/api/views/repo_group_api.py | 13 +++++++++---- rhodecode/api/views/user_group_api.py | 16 ++++++++++++---- rhodecode/apps/admin/views/permissions.py | 6 +++--- rhodecode/apps/admin/views/repo_groups.py | 3 ++- rhodecode/apps/admin/views/repositories.py | 3 ++- rhodecode/apps/admin/views/user_groups.py | 4 +++- rhodecode/apps/admin/views/users.py | 2 +- .../views/repo_group_permissions.py | 17 ++--------------- .../repo_group/views/repo_group_settings.py | 3 ++- .../apps/repository/views/repo_checks.py | 3 ++- rhodecode/apps/repository/views/repo_forks.py | 3 ++- .../apps/repository/views/repo_permissions.py | 16 ++-------------- .../apps/repository/views/repo_settings.py | 3 ++- .../views/repo_settings_advanced.py | 3 ++- rhodecode/apps/user_group/views/__init__.py | 4 ++-- rhodecode/model/permission.py | 19 +++++++++++++++++++ 17 files changed, 76 insertions(+), 55 deletions(-) diff --git a/rhodecode/api/views/repo_api.py b/rhodecode/api/views/repo_api.py index 835b94ec..de04351c 100644 --- a/rhodecode/api/views/repo_api.py +++ b/rhodecode/api/views/repo_api.py @@ -43,6 +43,7 @@ from rhodecode.model.comment import CommentsModel from rhodecode.model.db import ( Session, ChangesetStatus, RepositoryField, Repository, RepoGroup, ChangesetComment) +from rhodecode.model.permission import PermissionModel from rhodecode.model.repo import RepoModel from rhodecode.model.scm import ScmModel, RepoList from rhodecode.model.settings import SettingsModel, VcsSettingsModel @@ -1771,8 +1772,9 @@ def grant_user_permission(request, apiuser, repoid, userid, perm): } audit_logger.store_api( 'repo.edit.permissions', action_data=action_data, user=apiuser, repo=repo) - Session().commit() + PermissionModel().flush_user_permission_caches(changes) + return { 'msg': 'Granted perm: `%s` for user: `%s` in repo: `%s`' % ( perm.permission_name, user.username, repo.repo_name @@ -1833,8 +1835,9 @@ def revoke_user_permission(request, apiuser, repoid, userid): } audit_logger.store_api( 'repo.edit.permissions', action_data=action_data, user=apiuser, repo=repo) - Session().commit() + PermissionModel().flush_user_permission_caches(changes) + return { 'msg': 'Revoked perm for user: `%s` in repo: `%s`' % ( user.username, repo.repo_name @@ -1919,8 +1922,9 @@ def grant_user_group_permission(request, apiuser, repoid, usergroupid, perm): } audit_logger.store_api( 'repo.edit.permissions', action_data=action_data, user=apiuser, repo=repo) - Session().commit() + PermissionModel().flush_user_permission_caches(changes) + return { 'msg': 'Granted perm: `%s` for user group: `%s` in ' 'repo: `%s`' % ( @@ -1992,8 +1996,9 @@ def revoke_user_group_permission(request, apiuser, repoid, usergroupid): } audit_logger.store_api( 'repo.edit.permissions', action_data=action_data, user=apiuser, repo=repo) - Session().commit() + PermissionModel().flush_user_permission_caches(changes) + return { 'msg': 'Revoked perm for user group: `%s` in repo: `%s`' % ( user_group.users_group_name, repo.repo_name diff --git a/rhodecode/api/views/repo_group_api.py b/rhodecode/api/views/repo_group_api.py index d2227db7..7f7febe3 100644 --- a/rhodecode/api/views/repo_group_api.py +++ b/rhodecode/api/views/repo_group_api.py @@ -31,6 +31,7 @@ from rhodecode.lib import audit_logger from rhodecode.lib.auth import ( HasRepoGroupPermissionAnyApi, HasUserGroupPermissionAnyApi) from rhodecode.model.db import Session +from rhodecode.model.permission import PermissionModel from rhodecode.model.repo_group import RepoGroupModel from rhodecode.model.scm import RepoGroupList from rhodecode.model import validation_schema @@ -465,8 +466,9 @@ def grant_user_permission_to_repo_group( audit_logger.store_api( 'repo_group.edit.permissions', action_data=action_data, user=apiuser) - Session().commit() + PermissionModel().flush_user_permission_caches(changes) + return { 'msg': 'Granted perm: `%s` (recursive:%s) for user: ' '`%s` in repo group: `%s`' % ( @@ -548,8 +550,9 @@ def revoke_user_permission_from_repo_group( audit_logger.store_api( 'repo_group.edit.permissions', action_data=action_data, user=apiuser) - Session().commit() + PermissionModel().flush_user_permission_caches(changes) + return { 'msg': 'Revoked perm (recursive:%s) for user: ' '`%s` in repo group: `%s`' % ( @@ -641,8 +644,9 @@ def grant_user_group_permission_to_repo_group( audit_logger.store_api( 'repo_group.edit.permissions', action_data=action_data, user=apiuser) - Session().commit() + PermissionModel().flush_user_permission_caches(changes) + return { 'msg': 'Granted perm: `%s` (recursive:%s) ' 'for user group: `%s` in repo group: `%s`' % ( @@ -733,8 +737,9 @@ def revoke_user_group_permission_from_repo_group( audit_logger.store_api( 'repo_group.edit.permissions', action_data=action_data, user=apiuser) - Session().commit() + PermissionModel().flush_user_permission_caches(changes) + return { 'msg': 'Revoked perm (recursive:%s) for user group: ' '`%s` in repo group: `%s`' % ( diff --git a/rhodecode/api/views/user_group_api.py b/rhodecode/api/views/user_group_api.py index 3f9903e9..3c26dddf 100644 --- a/rhodecode/api/views/user_group_api.py +++ b/rhodecode/api/views/user_group_api.py @@ -29,6 +29,7 @@ from rhodecode.lib import audit_logger from rhodecode.lib.auth import HasUserGroupPermissionAnyApi, HasPermissionAnyApi from rhodecode.lib.exceptions import UserGroupAssignedException from rhodecode.model.db import Session +from rhodecode.model.permission import PermissionModel from rhodecode.model.scm import UserGroupList from rhodecode.model.user_group import UserGroupModel from rhodecode.model import validation_schema @@ -266,6 +267,10 @@ def create_user_group( 'user_group.create', action_data={'data': creation_data}, user=apiuser) Session().commit() + + affected_user_ids = [apiuser.user_id, owner.user_id] + PermissionModel().trigger_permission_flush(affected_user_ids) + return { 'msg': 'created new user group `%s`' % group_name, 'user_group': creation_data @@ -649,8 +654,9 @@ def grant_user_permission_to_user_group( audit_logger.store_api( 'user_group.edit.permissions', action_data=action_data, user=apiuser) - Session().commit() + PermissionModel().flush_user_permission_caches(changes) + return { 'msg': 'Granted perm: `%s` for user: `%s` in user group: `%s`' % ( @@ -718,8 +724,9 @@ def revoke_user_permission_from_user_group( audit_logger.store_api( 'user_group.edit.permissions', action_data=action_data, user=apiuser) - Session().commit() + PermissionModel().flush_user_permission_caches(changes) + return { 'msg': 'Revoked perm for user: `%s` in user group: `%s`' % ( user.username, user_group.users_group_name @@ -795,8 +802,9 @@ def grant_user_group_permission_to_user_group( audit_logger.store_api( 'user_group.edit.permissions', action_data=action_data, user=apiuser) - Session().commit() + PermissionModel().flush_user_permission_caches(changes) + return { 'msg': 'Granted perm: `%s` for user group: `%s` ' 'in user group: `%s`' % ( @@ -873,8 +881,8 @@ def revoke_user_group_permission_from_user_group( audit_logger.store_api( 'user_group.edit.permissions', action_data=action_data, user=apiuser) - Session().commit() + PermissionModel().flush_user_permission_caches(changes) return { 'msg': 'Revoked perm for user group: ' diff --git a/rhodecode/apps/admin/views/permissions.py b/rhodecode/apps/admin/views/permissions.py index d2fe6eeb..083e5da8 100644 --- a/rhodecode/apps/admin/views/permissions.py +++ b/rhodecode/apps/admin/views/permissions.py @@ -142,7 +142,7 @@ class AdminPermissionsView(BaseAppView, DataGridAppView): category='error') affected_user_ids = [User.get_default_user().user_id] - events.trigger(events.UserPermissionsChange(affected_user_ids)) + PermissionModel().trigger_permission_flush(affected_user_ids) raise HTTPFound(h.route_path('admin_permissions_application')) @@ -218,7 +218,7 @@ class AdminPermissionsView(BaseAppView, DataGridAppView): category='error') affected_user_ids = [User.get_default_user().user_id] - events.trigger(events.UserPermissionsChange(affected_user_ids)) + PermissionModel().trigger_permission_flush(affected_user_ids) raise HTTPFound(h.route_path('admin_permissions_object')) @@ -320,7 +320,7 @@ class AdminPermissionsView(BaseAppView, DataGridAppView): category='error') affected_user_ids = [User.get_default_user().user_id] - events.trigger(events.UserPermissionsChange(affected_user_ids)) + PermissionModel().trigger_permission_flush(affected_user_ids) raise HTTPFound(h.route_path('admin_permissions_global')) diff --git a/rhodecode/apps/admin/views/repo_groups.py b/rhodecode/apps/admin/views/repo_groups.py index a4ae38e2..af8f0fbb 100644 --- a/rhodecode/apps/admin/views/repo_groups.py +++ b/rhodecode/apps/admin/views/repo_groups.py @@ -36,6 +36,7 @@ from rhodecode.lib.auth import ( from rhodecode.lib import helpers as h, audit_logger from rhodecode.lib.utils2 import safe_int, safe_unicode, datetime_to_time from rhodecode.model.forms import RepoGroupForm +from rhodecode.model.permission import PermissionModel from rhodecode.model.repo_group import RepoGroupModel from rhodecode.model.scm import RepoGroupList from rhodecode.model.db import ( @@ -354,7 +355,7 @@ class AdminRepoGroupsView(BaseAppView, DataGridAppView): copy_perms = [perm['user_id'] for perm in user_group_perms] # also include those newly created by copy affected_user_ids.extend(copy_perms) - events.trigger(events.UserPermissionsChange(affected_user_ids)) + PermissionModel().trigger_permission_flush(affected_user_ids) raise HTTPFound( h.route_path('repo_group_home', diff --git a/rhodecode/apps/admin/views/repositories.py b/rhodecode/apps/admin/views/repositories.py index e9e26592..240ddd5e 100644 --- a/rhodecode/apps/admin/views/repositories.py +++ b/rhodecode/apps/admin/views/repositories.py @@ -39,6 +39,7 @@ from rhodecode.lib import helpers as h from rhodecode.lib.utils import repo_name_slug from rhodecode.lib.utils2 import safe_int, safe_unicode from rhodecode.model.forms import RepoForm +from rhodecode.model.permission import PermissionModel from rhodecode.model.repo import RepoModel from rhodecode.model.scm import RepoList, RepoGroupList, ScmModel from rhodecode.model.settings import SettingsModel @@ -182,7 +183,7 @@ class AdminReposView(BaseAppView, DataGridAppView): if copy_permissions: # permission flush is done in repo creating pass - events.trigger(events.UserPermissionsChange(affected_user_ids)) + PermissionModel().trigger_permission_flush(affected_user_ids) raise HTTPFound( h.route_path('repo_creating', repo_name=repo_name, diff --git a/rhodecode/apps/admin/views/user_groups.py b/rhodecode/apps/admin/views/user_groups.py index a12cdeb2..397bd44f 100644 --- a/rhodecode/apps/admin/views/user_groups.py +++ b/rhodecode/apps/admin/views/user_groups.py @@ -266,6 +266,8 @@ class AdminUserGroupsView(BaseAppView, DataGridAppView): % user_group_name, category='error') raise HTTPFound(h.route_path('user_groups_new')) - events.trigger(events.UserPermissionsChange([self._rhodecode_user.user_id])) + affected_user_ids = [self._rhodecode_user.user_id] + PermissionModel().trigger_permission_flush(affected_user_ids) + raise HTTPFound( h.route_path('edit_user_group', user_group_id=user_group_id)) diff --git a/rhodecode/apps/admin/views/users.py b/rhodecode/apps/admin/views/users.py index 9013651b..08710d01 100644 --- a/rhodecode/apps/admin/views/users.py +++ b/rhodecode/apps/admin/views/users.py @@ -597,7 +597,7 @@ class UsersView(UserAppView): category='error') affected_user_ids = [user_id] - events.trigger(events.UserPermissionsChange(affected_user_ids)) + PermissionModel().trigger_permission_flush(affected_user_ids) raise HTTPFound(h.route_path('user_edit_global_perms', user_id=user_id)) @LoginRequired() diff --git a/rhodecode/apps/repo_group/views/repo_group_permissions.py b/rhodecode/apps/repo_group/views/repo_group_permissions.py index 0063c971..9ab41cac 100644 --- a/rhodecode/apps/repo_group/views/repo_group_permissions.py +++ b/rhodecode/apps/repo_group/views/repo_group_permissions.py @@ -23,14 +23,12 @@ import logging from pyramid.view import view_config from pyramid.httpexceptions import HTTPFound -from rhodecode import events from rhodecode.apps._base import RepoGroupAppView from rhodecode.lib import helpers as h from rhodecode.lib import audit_logger from rhodecode.lib.auth import ( LoginRequired, HasRepoGroupPermissionAnyDecorator, CSRFRequired) -from rhodecode.lib.utils2 import safe_int -from rhodecode.model.db import UserGroup +from rhodecode.model.permission import PermissionModel from rhodecode.model.repo_group import RepoGroupModel from rhodecode.model.forms import RepoGroupPermsForm from rhodecode.model.meta import Session @@ -98,18 +96,7 @@ class RepoGroupPermissionsView(RepoGroupAppView): Session().commit() h.flash(_('Repository Group permissions updated'), category='success') - - affected_user_ids = [] - for change in changes['added'] + changes['updated'] + changes['deleted']: - if change['type'] == 'user': - affected_user_ids.append(change['id']) - if change['type'] == 'user_group': - user_group = UserGroup.get(safe_int(change['id'])) - if user_group: - group_members_ids = [x.user_id for x in user_group.members] - affected_user_ids.extend(group_members_ids) - - events.trigger(events.UserPermissionsChange(affected_user_ids)) + PermissionModel().flush_user_permission_caches(changes) raise HTTPFound( h.route_path('edit_repo_group_perms', diff --git a/rhodecode/apps/repo_group/views/repo_group_settings.py b/rhodecode/apps/repo_group/views/repo_group_settings.py index a9d92a8a..6ec77494 100644 --- a/rhodecode/apps/repo_group/views/repo_group_settings.py +++ b/rhodecode/apps/repo_group/views/repo_group_settings.py @@ -33,6 +33,7 @@ from rhodecode.lib.auth import ( LoginRequired, HasPermissionAll, HasRepoGroupPermissionAny, HasRepoGroupPermissionAnyDecorator, CSRFRequired) from rhodecode.model.db import Session, RepoGroup, User +from rhodecode.model.permission import PermissionModel from rhodecode.model.scm import RepoGroupList from rhodecode.model.repo_group import RepoGroupModel from rhodecode.model.validation_schema.schemas import repo_group_schema @@ -187,7 +188,7 @@ class RepoGroupSettingsView(RepoGroupAppView): owner = User.get_by_username(schema_data['repo_group_owner']) owner_id = owner.user_id if owner else self._rhodecode_user.user_id affected_user_ids.extend([self._rhodecode_user.user_id, owner_id]) - events.trigger(events.UserPermissionsChange(affected_user_ids)) + PermissionModel().trigger_permission_flush(affected_user_ids) raise HTTPFound( h.route_path('edit_repo_group', repo_group_name=new_repo_group_name)) diff --git a/rhodecode/apps/repository/views/repo_checks.py b/rhodecode/apps/repository/views/repo_checks.py index 2cf9542c..5e67a5fe 100644 --- a/rhodecode/apps/repository/views/repo_checks.py +++ b/rhodecode/apps/repository/views/repo_checks.py @@ -28,6 +28,7 @@ from rhodecode.apps._base import BaseAppView from rhodecode.lib import helpers as h from rhodecode.lib.auth import (NotAnonymous, HasRepoPermissionAny) from rhodecode.model.db import Repository +from rhodecode.model.permission import PermissionModel from rhodecode.model.validation_schema.types import RepoNameType log = logging.getLogger(__name__) @@ -122,4 +123,4 @@ class RepoChecksView(BaseAppView): # repo is finished and created, we flush the permissions now user_group_perms = db_repo.permissions(expand_from_user_groups=True) affected_user_ids = [perm['user_id'] for perm in user_group_perms] - events.trigger(events.UserPermissionsChange(affected_user_ids)) + PermissionModel().trigger_permission_flush(affected_user_ids) diff --git a/rhodecode/apps/repository/views/repo_forks.py b/rhodecode/apps/repository/views/repo_forks.py index eb3b8667..22ff7eb8 100644 --- a/rhodecode/apps/repository/views/repo_forks.py +++ b/rhodecode/apps/repository/views/repo_forks.py @@ -36,6 +36,7 @@ from rhodecode.lib.auth import ( import rhodecode.lib.helpers as h from rhodecode.lib.celerylib.utils import get_task_id from rhodecode.model.db import coalesce, or_, Repository, RepoGroup +from rhodecode.model.permission import PermissionModel from rhodecode.model.repo import RepoModel from rhodecode.model.forms import RepoForkForm from rhodecode.model.scm import ScmModel, RepoGroupList @@ -259,7 +260,7 @@ class RepoForksView(RepoAppView, DataGridAppView): # permission flush is done in repo creating pass - events.trigger(events.UserPermissionsChange(affected_user_ids)) + PermissionModel().trigger_permission_flush(affected_user_ids) raise HTTPFound( h.route_path('repo_creating', repo_name=repo_name, diff --git a/rhodecode/apps/repository/views/repo_permissions.py b/rhodecode/apps/repository/views/repo_permissions.py index f04df6ce..aa2b13d8 100644 --- a/rhodecode/apps/repository/views/repo_permissions.py +++ b/rhodecode/apps/repository/views/repo_permissions.py @@ -23,16 +23,14 @@ import logging from pyramid.httpexceptions import HTTPFound from pyramid.view import view_config -from rhodecode import events from rhodecode.apps._base import RepoAppView from rhodecode.lib import helpers as h from rhodecode.lib import audit_logger from rhodecode.lib.auth import ( LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired) -from rhodecode.lib.utils2 import safe_int -from rhodecode.model.db import UserGroup from rhodecode.model.forms import RepoPermsForm from rhodecode.model.meta import Session +from rhodecode.model.permission import PermissionModel from rhodecode.model.repo import RepoModel log = logging.getLogger(__name__) @@ -91,17 +89,7 @@ class RepoSettingsPermissionsView(RepoAppView): Session().commit() h.flash(_('Repository permissions updated'), category='success') - affected_user_ids = [] - for change in changes['added'] + changes['updated'] + changes['deleted']: - if change['type'] == 'user': - affected_user_ids.append(change['id']) - if change['type'] == 'user_group': - user_group = UserGroup.get(safe_int(change['id'])) - if user_group: - group_members_ids = [x.user_id for x in user_group.members] - affected_user_ids.extend(group_members_ids) - - events.trigger(events.UserPermissionsChange(affected_user_ids)) + PermissionModel().flush_user_permission_caches(changes) raise HTTPFound( h.route_path('edit_repo_perms', repo_name=self.db_repo_name)) diff --git a/rhodecode/apps/repository/views/repo_settings.py b/rhodecode/apps/repository/views/repo_settings.py index e30c8555..04ddaeda 100644 --- a/rhodecode/apps/repository/views/repo_settings.py +++ b/rhodecode/apps/repository/views/repo_settings.py @@ -33,6 +33,7 @@ from rhodecode.lib.auth import ( LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired) from rhodecode.model.db import RepositoryField, RepoGroup, Repository, User from rhodecode.model.meta import Session +from rhodecode.model.permission import PermissionModel from rhodecode.model.repo import RepoModel from rhodecode.model.scm import RepoGroupList, ScmModel from rhodecode.model.validation_schema.schemas import repo_schema @@ -184,7 +185,7 @@ class RepoSettingsView(RepoAppView): owner = User.get_by_username(schema_data['repo_owner']) owner_id = owner.user_id if owner else self._rhodecode_user.user_id affected_user_ids.extend([self._rhodecode_user.user_id, owner_id]) - events.trigger(events.UserPermissionsChange(affected_user_ids)) + PermissionModel().trigger_permission_flush(affected_user_ids) raise HTTPFound( h.route_path('edit_repo', repo_name=new_repo_name)) diff --git a/rhodecode/apps/repository/views/repo_settings_advanced.py b/rhodecode/apps/repository/views/repo_settings_advanced.py index 10436a30..9f38cf7c 100644 --- a/rhodecode/apps/repository/views/repo_settings_advanced.py +++ b/rhodecode/apps/repository/views/repo_settings_advanced.py @@ -34,6 +34,7 @@ from rhodecode.lib.exceptions import AttachedForksError, AttachedPullRequestsErr from rhodecode.lib.utils2 import safe_int from rhodecode.lib.vcs import RepositoryError from rhodecode.model.db import Session, UserFollowing, User, Repository +from rhodecode.model.permission import PermissionModel from rhodecode.model.repo import RepoModel from rhodecode.model.scm import ScmModel @@ -110,7 +111,7 @@ class RepoSettingsView(RepoAppView): # flush permissions for all users defined in permissions affected_user_ids = self._get_users_with_permissions().keys() - events.trigger(events.UserPermissionsChange(affected_user_ids)) + PermissionModel().trigger_permission_flush(affected_user_ids) raise HTTPFound(h.route_path('home')) diff --git a/rhodecode/apps/user_group/views/__init__.py b/rhodecode/apps/user_group/views/__init__.py index 00ac3f42..1819348f 100644 --- a/rhodecode/apps/user_group/views/__init__.py +++ b/rhodecode/apps/user_group/views/__init__.py @@ -199,7 +199,7 @@ class UserGroupsView(UserGroupAppView): affected_user_ids.append(self._rhodecode_user.user_id) affected_user_ids.append(owner_id) - events.trigger(events.UserPermissionsChange(affected_user_ids)) + PermissionModel().trigger_permission_flush(affected_user_ids) Session().commit() except formencode.Invalid as errors: @@ -383,7 +383,7 @@ class UserGroupsView(UserGroupAppView): group_members_ids = [x.user_id for x in user_group.members] affected_user_ids.extend(group_members_ids) - events.trigger(events.UserPermissionsChange(affected_user_ids)) + PermissionModel().trigger_permission_flush(affected_user_ids) raise HTTPFound( h.route_path('edit_user_group_perms', user_group_id=user_group_id)) diff --git a/rhodecode/model/permission.py b/rhodecode/model/permission.py index 33c571ce..6c064f92 100644 --- a/rhodecode/model/permission.py +++ b/rhodecode/model/permission.py @@ -28,6 +28,7 @@ import traceback from sqlalchemy.exc import DatabaseError +from rhodecode import events from rhodecode.model import BaseModel from rhodecode.model.db import ( User, Permission, UserToPerm, UserRepoToPerm, UserRepoGroupToPerm, @@ -556,3 +557,21 @@ class PermissionModel(BaseModel): self.sa.rollback() raise + def trigger_permission_flush(self, affected_user_ids): + events.trigger(events.UserPermissionsChange(affected_user_ids)) + + def flush_user_permission_caches(self, changes, affected_user_ids=None): + affected_user_ids = affected_user_ids or [] + + for change in changes['added'] + changes['updated'] + changes['deleted']: + if change['type'] == 'user': + affected_user_ids.append(change['id']) + if change['type'] == 'user_group': + user_group = UserGroup.get(safe_int(change['id'])) + if user_group: + group_members_ids = [x.user_id for x in user_group.members] + affected_user_ids.extend(group_members_ids) + + self.trigger_permission_flush(affected_user_ids) + + return affected_user_ids From e56069f76a535ea37becde4128d97ad6392a11e4 Mon Sep 17 00:00:00 2001 From: Marcin Kuzminski Date: Mon, 26 Aug 2019 16:58:25 +0200 Subject: [PATCH 12/23] security: fixed XSS in file editing. --- rhodecode/apps/repository/views/repo_files.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rhodecode/apps/repository/views/repo_files.py b/rhodecode/apps/repository/views/repo_files.py index a69ed758..81fa45f5 100644 --- a/rhodecode/apps/repository/views/repo_files.py +++ b/rhodecode/apps/repository/views/repo_files.py @@ -1230,7 +1230,7 @@ class RepoFilesView(RepoAppView): default_redirect_url = h.route_path('repo_commit', repo_name=self.db_repo_name, commit_id=commit_id) if content == old_content and node_path == org_node_path: - h.flash(_('No changes detected on {}').format(org_node_path), + h.flash(_('No changes detected on {}').format(h.escape(org_node_path)), category='warning') raise HTTPFound(default_redirect_url) From b0958699f54f80b14b6d56c9ecfa1cc58f0c9b01 Mon Sep 17 00:00:00 2001 From: Daniel Dourvaris Date: Mon, 26 Aug 2019 21:49:06 +0200 Subject: [PATCH 13/23] diffs: handle paths with quotes in diffs. --- rhodecode/lib/vcs/backends/git/diff.py | 4 ++-- rhodecode/lib/vcs/backends/hg/diff.py | 6 +++--- rhodecode/lib/vcs/backends/svn/diff.py | 5 ++--- rhodecode/tests/fixtures/git_diff_js_chars.diff | 7 +++++++ rhodecode/tests/lib/test_diffs.py | 8 ++++++++ 5 files changed, 22 insertions(+), 8 deletions(-) create mode 100644 rhodecode/tests/fixtures/git_diff_js_chars.diff diff --git a/rhodecode/lib/vcs/backends/git/diff.py b/rhodecode/lib/vcs/backends/git/diff.py index c00e3f6a..fa6ba042 100644 --- a/rhodecode/lib/vcs/backends/git/diff.py +++ b/rhodecode/lib/vcs/backends/git/diff.py @@ -44,6 +44,6 @@ class GitDiff(base.Diff): (?:^index[ ](?P[0-9A-Fa-f]+) \.\.(?P[0-9A-Fa-f]+)[ ]?(?P.+)?(?:\n|$))? (?:^(?PGIT[ ]binary[ ]patch)(?:\n|$))? - (?:^---[ ](a/(?P.+)|/dev/null)(?:\n|$))? - (?:^\+\+\+[ ](b/(?P.+)|/dev/null)(?:\n|$))? + (?:^---[ ]("?a/(?P.+)|/dev/null)(?:\n|$))? + (?:^\+\+\+[ ]("?b/(?P.+)|/dev/null)(?:\n|$))? """, re.VERBOSE | re.MULTILINE) diff --git a/rhodecode/lib/vcs/backends/hg/diff.py b/rhodecode/lib/vcs/backends/hg/diff.py index d14d1ded..f7c9c1fe 100644 --- a/rhodecode/lib/vcs/backends/hg/diff.py +++ b/rhodecode/lib/vcs/backends/hg/diff.py @@ -19,7 +19,7 @@ # and proprietary license terms, please see https://rhodecode.com/licenses/ """ -GIT diff module +HG diff module """ import re @@ -44,6 +44,6 @@ class MercurialDiff(base.Diff): (?:^index[ ](?P[0-9A-Fa-f]+) \.\.(?P[0-9A-Fa-f]+)[ ]?(?P.+)?(?:\n|$))? (?:^(?PGIT[ ]binary[ ]patch)(?:\n|$))? - (?:^---[ ](a/(?P.+)|/dev/null)(?:\n|$))? - (?:^\+\+\+[ ](b/(?P.+)|/dev/null)(?:\n|$))? + (?:^---[ ]("?a/(?P.+)|/dev/null)(?:\n|$))? + (?:^\+\+\+[ ]("?b/(?P.+)|/dev/null)(?:\n|$))? """, re.VERBOSE | re.MULTILINE) diff --git a/rhodecode/lib/vcs/backends/svn/diff.py b/rhodecode/lib/vcs/backends/svn/diff.py index 84ac806b..41ca0725 100644 --- a/rhodecode/lib/vcs/backends/svn/diff.py +++ b/rhodecode/lib/vcs/backends/svn/diff.py @@ -18,7 +18,6 @@ # RhodeCode Enterprise Edition, including its added features, Support services, # and proprietary license terms, please see https://rhodecode.com/licenses/ - """ SVN diff module """ @@ -47,6 +46,6 @@ class SubversionDiff(base.Diff): (?:^index[ ](?P[0-9A-Fa-f]+) \.\.(?P[0-9A-Fa-f]+)[ ]?(?P.+)?(?:\n|$))? (?:^(?PGIT[ ]binary[ ]patch)(?:\n|$))? - (?:^---[ ](a/(?P.+)|/dev/null)\t\(revision[ ]\d+\)(?:\n|$))? - (?:^\+\+\+[ ](b/(?P.+)|/dev/null)\t\(revision[ ]\d+\)(?:\n|$))? + (?:^---[ ]("?a/(?P.+)|/dev/null)\t\(revision[ ]\d+\)(?:\n|$))? + (?:^\+\+\+[ ]("?b/(?P.+)|/dev/null)\t\(revision[ ]\d+\)(?:\n|$))? """, re.VERBOSE | re.MULTILINE) diff --git a/rhodecode/tests/fixtures/git_diff_js_chars.diff b/rhodecode/tests/fixtures/git_diff_js_chars.diff new file mode 100644 index 00000000..c04e878c --- /dev/null +++ b/rhodecode/tests/fixtures/git_diff_js_chars.diff @@ -0,0 +1,7 @@ +diff --git "a/\">/\">.txt" "b/\">/\">.txt" +index e69de29..8eb97de 100644 +--- "a/\">/\">.txt" ++++ "b/\">/\">.txt" +@@ -0,0 +1 @@ ++Ehlo eglo +\ No newline at end of file diff --git a/rhodecode/tests/lib/test_diffs.py b/rhodecode/tests/lib/test_diffs.py index 4b8fe11b..ac4081d1 100644 --- a/rhodecode/tests/lib/test_diffs.py +++ b/rhodecode/tests/lib/test_diffs.py @@ -342,6 +342,14 @@ DIFF_FIXTURES = [ 'binary': True, 'ops': {CHMOD_FILENODE: 'modified file chmod 100644 => 100755'}}) ]), + ('git', + 'git_diff_js_chars.diff', + [('\\">/\\">.txt', 'M', + {'added': 1, + 'deleted': 0, + 'binary': False, + 'ops': {MOD_FILENODE: 'modified file'}}) + ]), ('git', 'git_diff_rename_file.diff', [('file.xls', 'M', From c2e4a92f21736f84a3d81161b373a0d3c8f969b0 Mon Sep 17 00:00:00 2001 From: Marcin Kuzminski Date: Mon, 9 Sep 2019 10:47:13 +0200 Subject: [PATCH 14/23] svn: handle non-ascii message editing. --- rhodecode/lib/middleware/simplesvn.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rhodecode/lib/middleware/simplesvn.py b/rhodecode/lib/middleware/simplesvn.py index 5ef47e36..9f7474de 100644 --- a/rhodecode/lib/middleware/simplesvn.py +++ b/rhodecode/lib/middleware/simplesvn.py @@ -29,7 +29,7 @@ from pyramid.httpexceptions import HTTPNotAcceptable from rhodecode.lib import rc_cache from rhodecode.lib.middleware import simplevcs from rhodecode.lib.utils import is_valid_repo -from rhodecode.lib.utils2 import str2bool, safe_int +from rhodecode.lib.utils2 import str2bool, safe_int, safe_str from rhodecode.lib.ext_json import json from rhodecode.lib.hooks_daemon import store_txn_id_data @@ -98,7 +98,8 @@ class SimpleSvnApp(object): raise if response.status_code not in [200, 401]: - text = '\n{}'.format(response.text) if response.text else '' + from rhodecode.lib.utils2 import safe_str + text = '\n{}'.format(safe_str(response.text)) if response.text else '' if response.status_code >= 500: log.error('Got SVN response:%s with text:`%s`', response, text) else: From 8f1e6c85cb9adf657ef79d100324f00d486d9210 Mon Sep 17 00:00:00 2001 From: Marcin Kuzminski Date: Tue, 10 Sep 2019 15:28:20 +0200 Subject: [PATCH 15/23] pull-requests: handle exceptions in state change and improve logging. --- rhodecode/model/db.py | 26 ++++++++++++++++++++------ rhodecode/model/pull_request.py | 6 ++++-- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/rhodecode/model/db.py b/rhodecode/model/db.py index 7de2b511..c05fe836 100644 --- a/rhodecode/model/db.py +++ b/rhodecode/model/db.py @@ -3772,21 +3772,35 @@ class _SetState(object): self._pr = pull_request self._org_state = back_state or pull_request.pull_request_state self._pr_state = pr_state + self._current_state = None def __enter__(self): log.debug('StateLock: entering set state context, setting state to: `%s`', self._pr_state) - self._pr.pull_request_state = self._pr_state - Session().add(self._pr) - Session().commit() + self.set_pr_state(self._pr_state) + return self def __exit__(self, exc_type, exc_val, exc_tb): + if exc_val is not None: + log.error(traceback.format_exc(exc_tb)) + return None + + self.set_pr_state(self._org_state) log.debug('StateLock: exiting set state context, setting state to: `%s`', self._org_state) - self._pr.pull_request_state = self._org_state - Session().add(self._pr) - Session().commit() + @property + def state(self): + return self._current_state + def set_pr_state(self, pr_state): + try: + self._pr.pull_request_state = pr_state + Session().add(self._pr) + Session().commit() + self._current_state = pr_state + except Exception: + log.exception('Failed to set PullRequest %s state to %s', self._pr, pr_state) + raise class _PullRequestBase(BaseModel): """ diff --git a/rhodecode/model/pull_request.py b/rhodecode/model/pull_request.py index cac7c69e..3b0bb558 100644 --- a/rhodecode/model/pull_request.py +++ b/rhodecode/model/pull_request.py @@ -507,10 +507,10 @@ class PullRequestModel(BaseModel): # operation pull_request = PullRequest.get(pull_request.pull_request_id) - # set as merging, for simulation, and if finished to created so we mark + # set as merging, for merge simulation, and if finished to created so we mark # simulation is working fine with pull_request.set_state(PullRequest.STATE_MERGING, - final_state=PullRequest.STATE_CREATED): + final_state=PullRequest.STATE_CREATED) as state_obj: MergeCheck.validate( pull_request, auth_user=auth_user, translator=translator) @@ -1099,6 +1099,8 @@ class PullRequestModel(BaseModel): if not reviewers_ids: return + log.debug('Notify following reviewers about pull-request %s', reviewers_ids) + pull_request_obj = pull_request # get the current participants of this pull request recipients = reviewers_ids From 006a425067f1d7f99c1efc7e0b0a0702435ca8f1 Mon Sep 17 00:00:00 2001 From: Marcin Kuzminski Date: Mon, 28 Oct 2019 14:16:40 +0100 Subject: [PATCH 16/23] tests: fixed PR tests after some code changes. --- rhodecode/api/tests/test_get_pull_request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rhodecode/api/tests/test_get_pull_request.py b/rhodecode/api/tests/test_get_pull_request.py index cd736820..e959126d 100644 --- a/rhodecode/api/tests/test_get_pull_request.py +++ b/rhodecode/api/tests/test_get_pull_request.py @@ -38,7 +38,7 @@ class TestGetPullRequest(object): pull_request = pr_util.create_pull_request(mergeable=True) id_, params = build_data( self.apikey, 'get_pull_request', - pullrequestid=pull_request.pull_request_id) + pullrequestid=pull_request.pull_request_id, merge_state=True) response = api_call(self.app, params) From 8753de9b1163f0c0998edb126f8201782f9c59d3 Mon Sep 17 00:00:00 2001 From: Marcin Kuzminski Date: Mon, 28 Oct 2019 11:09:38 +0100 Subject: [PATCH 17/23] diffs: fixed outdated files in pull-requests re-using the filediff raw_id for anchor generation. In some cases when there are no longer any files this caused error since filediff wasn't present. In addition this generated wrong ids since it used a last-defined attribute on a for loop. Fixes #5567 --- rhodecode/templates/codeblocks/diffs.mako | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rhodecode/templates/codeblocks/diffs.mako b/rhodecode/templates/codeblocks/diffs.mako index 09cb1990..7e2a1340 100644 --- a/rhodecode/templates/codeblocks/diffs.mako +++ b/rhodecode/templates/codeblocks/diffs.mako @@ -290,10 +290,12 @@ collapse_all = len(diffset.files) > collapse_when_files_over open_comments_in_file = [x for x in comments_dict['comments'] if x.outdated is False] if open_comments_in_file: display_state = '' + fid = str(id(filename)) %>
-
+
+