diff --git a/rhodecode/apps/admin/__init__.py b/rhodecode/apps/admin/__init__.py --- a/rhodecode/apps/admin/__init__.py +++ b/rhodecode/apps/admin/__init__.py @@ -420,5 +420,7 @@ def includeme(config): config.add_route(name='admin_home', pattern=ADMIN_PREFIX) config.include(admin_routes, route_prefix=ADMIN_PREFIX) + config.include('.subscribers') + # Scan module for configuration decorators. config.scan('.views', ignore='.tests') diff --git a/rhodecode/apps/admin/subscribers.py b/rhodecode/apps/admin/subscribers.py new file mode 100644 --- /dev/null +++ b/rhodecode/apps/admin/subscribers.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2016-2018 RhodeCode GmbH +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License, version 3 +# (only), as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# This program is dual-licensed. If you wish to learn more about the +# RhodeCode Enterprise Edition, including its added features, Support services, +# and proprietary license terms, please see https://rhodecode.com/licenses/ + +import logging + +from rhodecode import events + +log = logging.getLogger(__name__) + + +def trigger_user_permission_flush(event): + """ + Subscriber to the `UserPermissionChange`. This triggers the + automatic flush of permission caches, so the users affected receive new permissions + Right Away + """ + affected_user_ids = event.user_ids + + +def includeme(config): + config.add_subscriber(trigger_user_permission_flush, events.UserPermissionsChange) 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,6 +23,7 @@ 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 @@ -95,6 +96,14 @@ 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']) + + events.trigger(events.UserPermissionsChange(affected_user_ids)) + raise HTTPFound( h.route_path('edit_repo_group_perms', repo_group_name=self.db_repo_group_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,6 +23,7 @@ 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 @@ -39,8 +40,6 @@ class RepoSettingsPermissionsView(RepoAp def load_default_context(self): c = self._get_local_tmpl_context() - - return c @LoginRequired() @@ -85,5 +84,12 @@ 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']) + + events.trigger(events.UserPermissionsChange(affected_user_ids)) + raise HTTPFound( h.route_path('edit_repo_perms', repo_name=self.db_repo_name)) 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 @@ -28,6 +28,7 @@ from pyramid.view import view_config from pyramid.response import Response from pyramid.renderers import render +from rhodecode import events from rhodecode.lib.exceptions import ( RepoGroupAssignmentError, UserGroupAssignedException) from rhodecode.model.forms import ( @@ -183,6 +184,12 @@ class UserGroupsView(UserGroupAppView): h.flash(_('Updated user group %s') % updated_user_group, category='success') + + affected_user_ids = [] + for user_id in added_members + removed_members: + affected_user_ids.append(user_id) + events.trigger(events.UserPermissionsChange(affected_user_ids)) + Session().commit() except formencode.Invalid as errors: defaults = errors.value @@ -354,6 +361,14 @@ class UserGroupsView(UserGroupAppView): Session().commit() h.flash(_('User 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']) + + events.trigger(events.UserPermissionsChange(affected_user_ids)) + raise HTTPFound( h.route_path('edit_user_group_perms', user_group_id=user_group_id)) diff --git a/rhodecode/events/__init__.py b/rhodecode/events/__init__.py --- a/rhodecode/events/__init__.py +++ b/rhodecode/events/__init__.py @@ -49,11 +49,13 @@ def trigger(event, registry=None): if isinstance(event, RhodecodeEvent): integrations_event_handler(event) + from rhodecode.events.user import ( # noqa UserPreCreate, UserPostCreate, UserPreUpdate, - UserRegistered + UserRegistered, + UserPermissionsChange, ) from rhodecode.events.repo import ( # noqa diff --git a/rhodecode/events/user.py b/rhodecode/events/user.py --- a/rhodecode/events/user.py +++ b/rhodecode/events/user.py @@ -83,3 +83,22 @@ class UserPreUpdate(RhodecodeEvent): super(UserPreUpdate, self).__init__() self.user = user self.user_data = user_data + + +class UserPermissionsChange(RhodecodeEvent): + """ + This event should be triggered on an event that permissions of user might changed. + Currently this should be triggered on: + + - user added/removed from user group + - repo permissions changed + - repo group permissions changed + - user group permissions changed + + """ + name = 'user-permissions-change' + display_name = lazy_ugettext('user permissions change') + + def __init__(self, user_ids): + super(UserPermissionsChange, self).__init__() + self.user_ids = user_ids diff --git a/rhodecode/subscribers.py b/rhodecode/subscribers.py --- a/rhodecode/subscribers.py +++ b/rhodecode/subscribers.py @@ -102,6 +102,7 @@ def add_request_user_context(event): request.environ['rc_auth_user'] = auth_user request.environ['rc_req_id'] = req_id + def inject_app_settings(event): settings = event.app.registry.settings # inject info about available permissions