# HG changeset patch # User Marcin Kuzminski # Date 2019-08-20 08:48:36 # Node ID 85d5bce027f332b1771bacee8504ccff1b440bda # Parent 33e11360716388cc258cdd031d83cfa3d9f25182 permissions: properly flush user cache permissions in more cases of permission changes. - fixed #5560 diff --git a/rhodecode/api/views/repo_api.py b/rhodecode/api/views/repo_api.py --- a/rhodecode/api/views/repo_api.py +++ b/rhodecode/api/views/repo_api.py @@ -43,6 +43,7 @@ from rhodecode.model.comment import Comm 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 @@ -1783,8 +1784,9 @@ def grant_user_permission(request, apius } audit_logger.store_api( 'repo.edit.permissions', action_data=action_data, user=apiuser, repo=repo) + Session().commit() + PermissionModel().flush_user_permission_caches(changes) - Session().commit() return { 'msg': 'Granted perm: `%s` for user: `%s` in repo: `%s`' % ( perm.permission_name, user.username, repo.repo_name @@ -1845,8 +1847,9 @@ def revoke_user_permission(request, apiu } audit_logger.store_api( 'repo.edit.permissions', action_data=action_data, user=apiuser, repo=repo) + Session().commit() + PermissionModel().flush_user_permission_caches(changes) - Session().commit() return { 'msg': 'Revoked perm for user: `%s` in repo: `%s`' % ( user.username, repo.repo_name @@ -1931,8 +1934,9 @@ def grant_user_group_permission(request, } audit_logger.store_api( 'repo.edit.permissions', action_data=action_data, user=apiuser, repo=repo) + Session().commit() + PermissionModel().flush_user_permission_caches(changes) - Session().commit() return { 'msg': 'Granted perm: `%s` for user group: `%s` in ' 'repo: `%s`' % ( @@ -2004,8 +2008,9 @@ def revoke_user_group_permission(request } audit_logger.store_api( 'repo.edit.permissions', action_data=action_data, user=apiuser, repo=repo) + Session().commit() + PermissionModel().flush_user_permission_caches(changes) - Session().commit() 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 --- 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) - Session().commit() return { 'msg': 'Granted perm: `%s` (recursive:%s) for user: ' '`%s` in repo group: `%s`' % ( @@ -548,8 +550,9 @@ def revoke_user_permission_from_repo_gro audit_logger.store_api( 'repo_group.edit.permissions', action_data=action_data, user=apiuser) + Session().commit() + PermissionModel().flush_user_permission_caches(changes) - Session().commit() return { 'msg': 'Revoked perm (recursive:%s) for user: ' '`%s` in repo group: `%s`' % ( @@ -641,8 +644,9 @@ def grant_user_group_permission_to_repo_ audit_logger.store_api( 'repo_group.edit.permissions', action_data=action_data, user=apiuser) + Session().commit() + PermissionModel().flush_user_permission_caches(changes) - Session().commit() 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_re audit_logger.store_api( 'repo_group.edit.permissions', action_data=action_data, user=apiuser) + Session().commit() + PermissionModel().flush_user_permission_caches(changes) - Session().commit() 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 --- 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 @@ -268,6 +269,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 @@ -653,8 +658,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) - Session().commit() return { 'msg': 'Granted perm: `%s` for user: `%s` in user group: `%s`' % ( @@ -722,8 +728,9 @@ def revoke_user_permission_from_user_gro audit_logger.store_api( 'user_group.edit.permissions', action_data=action_data, user=apiuser) + Session().commit() + PermissionModel().flush_user_permission_caches(changes) - Session().commit() return { 'msg': 'Revoked perm for user: `%s` in user group: `%s`' % ( user.username, user_group.users_group_name @@ -799,8 +806,9 @@ def grant_user_group_permission_to_user_ audit_logger.store_api( 'user_group.edit.permissions', action_data=action_data, user=apiuser) + Session().commit() + PermissionModel().flush_user_permission_caches(changes) - Session().commit() return { 'msg': 'Granted perm: `%s` for user group: `%s` ' 'in user group: `%s`' % ( @@ -877,8 +885,8 @@ def revoke_user_group_permission_from_us 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 --- a/rhodecode/apps/admin/views/permissions.py +++ b/rhodecode/apps/admin/views/permissions.py @@ -143,7 +143,7 @@ class AdminPermissionsView(BaseAppView, 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')) @@ -219,7 +219,7 @@ class AdminPermissionsView(BaseAppView, 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')) @@ -321,7 +321,7 @@ class AdminPermissionsView(BaseAppView, 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 --- 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, D 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 --- 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 @@ -179,7 +180,7 @@ class AdminReposView(BaseAppView, DataGr 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 --- a/rhodecode/apps/admin/views/user_groups.py +++ b/rhodecode/apps/admin/views/user_groups.py @@ -266,6 +266,8 @@ class AdminUserGroupsView(BaseAppView, D % 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 --- 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 --- 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(RepoGroup 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 --- 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(RepoGroupApp 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 --- 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 BaseApp 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 --- 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 @@ -257,7 +258,7 @@ class RepoForksView(RepoAppView, DataGri # 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 --- 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(RepoAp 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 --- 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 --- 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 Att 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 --- 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 --- 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