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 @@ -917,12 +917,13 @@ def update_repo( ref_choices, _labels = ScmModel().get_repo_landing_revs(repo=repo) + old_values = repo.get_api_data() schema = repo_schema.RepoSchema().bind( repo_type_options=rhodecode.BACKENDS.keys(), repo_ref_options=ref_choices, # user caller user=apiuser, - old_values=repo.get_api_data()) + old_values=old_values) try: schema_data = schema.deserialize(dict( # we save old value, users cannot change type @@ -967,6 +968,9 @@ def update_repo( try: RepoModel().update(repo, **validated_updates) + audit_logger.store_api( + 'repo.edit', action_data={'old_data': old_values}, + user=apiuser, repo=repo) Session().commit() return { 'msg': 'updated repo ID:%s %s' % (repo.repo_id, repo.repo_name), @@ -1173,15 +1177,14 @@ def delete_repo(request, apiuser, repoid 'Cannot delete `%s` it still contains attached forks' % (repo.repo_name,) ) - repo_data = repo.get_api_data() + old_data = repo.get_api_data() RepoModel().delete(repo, forks=forks) repo = audit_logger.RepoWrap(repo_id=None, repo_name=repo.repo_name) audit_logger.store_api( - action='repo.delete', - action_data={'data': repo_data}, + 'repo.delete', action_data={'old_data': old_data}, user=apiuser, repo=repo) ScmModel().mark_for_invalidation(repo_name, delete=True) @@ -1472,7 +1475,7 @@ def comment_commit( rc_config = SettingsModel().get_all_settings() renderer = rc_config.get('rhodecode_markup_renderer', 'rst') status_change_label = ChangesetStatus.get_status_lbl(status) - comm = CommentsModel().create( + comment = CommentsModel().create( message, repo, user, commit_id=commit_id, status_change=status_change_label, status_change_type=status, @@ -1484,7 +1487,7 @@ def comment_commit( # also do a status change try: ChangesetStatusModel().set_status( - repo, status, user, comm, revision=commit_id, + repo, status, user, comment, revision=commit_id, dont_allow_on_closed_pull_request=True ) except StatusChangeOnClosedPullRequestError: @@ -1498,7 +1501,7 @@ def comment_commit( return { 'msg': ( 'Commented on commit `%s` for repository `%s`' % ( - comm.revision, repo.repo_name)), + comment.revision, repo.repo_name)), 'status_change': status, 'success': True, } @@ -1879,6 +1882,11 @@ def strip(request, apiuser, repoid, revi try: ScmModel().strip(repo, revision, branch) + audit_logger.store_api( + 'repo.commit.strip', action_data={'commit_id': revision}, + repo=repo, + user=apiuser, commit=True) + return { 'msg': 'Stripped commit %s from repo `%s`' % ( revision, 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 @@ -27,6 +27,7 @@ from rhodecode.api.utils import ( has_superadmin_permission, Optional, OAttr, get_user_or_error, get_repo_group_or_error, get_perm_or_error, get_user_group_or_error, get_origin, validate_repo_group_permissions, validate_set_owner_permissions) +from rhodecode.lib import audit_logger from rhodecode.lib.auth import ( HasRepoGroupPermissionAnyApi, HasUserGroupPermissionAnyApi) from rhodecode.model.db import Session @@ -222,6 +223,13 @@ def create_repo_group( group_name=validated_group_name, group_description=schema_data['repo_group_name'], copy_permissions=schema_data['repo_group_copy_permissions']) + Session().flush() + + repo_group_data = repo_group.get_api_data() + audit_logger.store_api( + 'repo_group.create', action_data={'data': repo_group_data}, + user=apiuser) + Session().commit() return { 'msg': 'Created new repo group `%s`' % validated_group_name, @@ -310,8 +318,13 @@ def update_repo_group( enable_locking=schema_data['repo_group_enable_locking'], ) + old_data = repo_group.get_api_data() try: RepoGroupModel().update(repo_group, validated_updates) + audit_logger.store_api( + 'repo_group.edit', action_data={'old_data': old_data}, + user=apiuser) + Session().commit() return { 'msg': 'updated repository group ID:%s %s' % ( @@ -365,8 +378,12 @@ def delete_repo_group(request, apiuser, validate_repo_group_permissions( apiuser, repogroupid, repo_group, ('group.admin',)) + old_data = repo_group.get_api_data() try: RepoGroupModel().delete(repo_group) + audit_logger.store_api( + 'repo_group.delete', action_data={'old_data': old_data}, + user=apiuser) Session().commit() return { 'msg': 'deleted repo group ID:%s %s' % diff --git a/rhodecode/api/views/user_api.py b/rhodecode/api/views/user_api.py --- a/rhodecode/api/views/user_api.py +++ b/rhodecode/api/views/user_api.py @@ -23,6 +23,7 @@ import logging from rhodecode.api import jsonrpc_method, JSONRPCError, JSONRPCForbidden from rhodecode.api.utils import ( Optional, OAttr, has_superadmin_permission, get_user_or_error, store_update) +from rhodecode.lib import audit_logger from rhodecode.lib.auth import AuthUser, PasswordGenerator from rhodecode.lib.exceptions import DefaultUserException from rhodecode.lib.utils2 import safe_int, str2bool @@ -251,6 +252,12 @@ def create_user(request, apiuser, userna force_password_change=Optional.extract(force_password_change), create_repo_group=create_repo_group ) + Session().flush() + creation_data = user.get_api_data() + audit_logger.store_api( + 'user.create', action_data={'data': creation_data}, + user=apiuser) + Session().commit() return { 'msg': 'created new user `%s`' % username, @@ -326,7 +333,7 @@ def update_user(request, apiuser, userid raise JSONRPCForbidden() user = get_user_or_error(userid) - + old_data = user.get_api_data() # only non optional arguments will be stored in updates updates = {} @@ -343,6 +350,9 @@ def update_user(request, apiuser, userid store_update(updates, extern_type, 'extern_type') user = UserModel().update_user(user, **updates) + audit_logger.store_api( + 'user.edit', action_data={'old_data': old_data}, + user=apiuser) Session().commit() return { 'msg': 'updated user ID:%s %s' % (user.user_id, user.username), @@ -405,9 +415,13 @@ def delete_user(request, apiuser, userid raise JSONRPCForbidden() user = get_user_or_error(userid) - + old_data = user.get_api_data() try: UserModel().delete(userid) + audit_logger.store_api( + 'user.delete', action_data={'old_data': old_data}, + user=apiuser) + Session().commit() return { 'msg': 'deleted user ID:%s %s' % (user.user_id, user.username), 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 @@ -24,6 +24,7 @@ from rhodecode.api import jsonrpc_method from rhodecode.api.utils import ( Optional, OAttr, store_update, has_superadmin_permission, get_origin, get_user_or_error, get_user_group_or_error, get_perm_or_error) +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 @@ -217,13 +218,18 @@ def create_user_group( owner = get_user_or_error(owner) active = Optional.extract(active) description = Optional.extract(description) - ug = UserGroupModel().create( + user_group = UserGroupModel().create( name=group_name, description=description, owner=owner, active=active) + Session().flush() + creation_data = user_group.get_api_data() + audit_logger.store_api( + 'user_group.create', action_data={'data': creation_data}, + user=apiuser) Session().commit() return { 'msg': 'created new user group `%s`' % group_name, - 'user_group': ug.get_api_data() + 'user_group': creation_data } except Exception: log.exception("Error occurred during creation of user group") @@ -291,6 +297,7 @@ def update_user_group(request, apiuser, if not isinstance(owner, Optional): owner = get_user_or_error(owner) + old_data = user_group.get_api_data() updates = {} store_update(updates, group_name, 'users_group_name') store_update(updates, description, 'user_group_description') @@ -298,6 +305,9 @@ def update_user_group(request, apiuser, store_update(updates, active, 'users_group_active') try: UserGroupModel().update(user_group, updates) + audit_logger.store_api( + 'user_group.edit', action_data={'old_data': old_data}, + user=apiuser) Session().commit() return { 'msg': 'updated user group ID:%s %s' % ( @@ -359,8 +369,12 @@ def delete_user_group(request, apiuser, raise JSONRPCError( 'user group `%s` does not exist' % (usergroupid,)) + old_data = user_group.get_api_data() try: UserGroupModel().delete(user_group) + audit_logger.store_api( + 'user_group.delete', action_data={'old_data': old_data}, + user=apiuser) Session().commit() return { 'msg': 'deleted user group ID:%s %s' % ( @@ -438,6 +452,12 @@ def add_user_to_user_group(request, apiu user.username, user_group.users_group_name ) msg = msg if success else 'User is already in that group' + if success: + user_data = user.get_api_data() + audit_logger.store_api( + 'user_group.edit.member.add', action_data={'user': user_data}, + user=apiuser) + Session().commit() return { @@ -501,6 +521,12 @@ def remove_user_from_user_group(request, user.username, user_group.users_group_name ) msg = msg if success else "User wasn't in group" + if success: + user_data = user.get_api_data() + audit_logger.store_api( + 'user_group.edit.member.delete', action_data={'user': user_data}, + user=apiuser) + Session().commit() return {'success': success, 'msg': msg} except Exception: 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 @@ -209,8 +209,8 @@ class AdminUsersView(BaseAppView, DataGr self.maybe_attach_token_scope(token) audit_logger.store_web( - action='user.edit.token.add', - action_data={'data': {'token': token_data, 'user': user_data}}, + 'user.edit.token.add', action_data={ + 'data': {'token': token_data, 'user': user_data}}, user=self._rhodecode_user, ) Session().commit() @@ -239,8 +239,8 @@ class AdminUsersView(BaseAppView, DataGr AuthTokenModel().delete(del_auth_token, c.user.user_id) audit_logger.store_web( - action='user.edit.token.delete', - action_data={'data': {'token': token_data, 'user': user_data}}, + 'user.edit.token.delete', action_data={ + 'data': {'token': token_data, 'user': user_data}}, user=self._rhodecode_user,) Session().commit() h.flash(_("Auth token successfully deleted"), category='success') @@ -284,8 +284,7 @@ class AdminUsersView(BaseAppView, DataGr try: UserModel().add_extra_email(c.user.user_id, email) audit_logger.store_web( - 'user.edit.email.add', - action_data={'email': email, 'user': user_data}, + 'user.edit.email.add', action_data={'email': email, 'user': user_data}, user=self._rhodecode_user) Session().commit() h.flash(_("Added new email address `%s` for user account") % email, @@ -318,8 +317,7 @@ class AdminUsersView(BaseAppView, DataGr user_data = c.user.get_api_data() user_model.delete_extra_email(c.user.user_id, email_id) audit_logger.store_web( - 'user.edit.email.delete', - action_data={'email': email, 'user': user_data}, + 'user.edit.email.delete', action_data={'email': email, 'user': user_data}, user=self._rhodecode_user) Session().commit() h.flash(_("Removed email address from user account"), @@ -379,8 +377,7 @@ class AdminUsersView(BaseAppView, DataGr try: user_model.add_extra_ip(c.user.user_id, ip, desc) audit_logger.store_web( - 'user.edit.ip.add', - action_data={'ip': ip, 'user': user_data}, + 'user.edit.ip.add', action_data={'ip': ip, 'user': user_data}, user=self._rhodecode_user) Session().commit() added.append(ip) @@ -420,8 +417,7 @@ class AdminUsersView(BaseAppView, DataGr ip = UserIpMap.query().get(ip_id).ip_addr user_model.delete_extra_ip(c.user.user_id, ip_id) audit_logger.store_web( - 'user.edit.ip.delete', - action_data={'ip': ip, 'user': user_data}, + 'user.edit.ip.delete', action_data={'ip': ip, 'user': user_data}, user=self._rhodecode_user) Session().commit() h.flash(_("Removed ip address from user whitelist"), category='success') diff --git a/rhodecode/apps/login/views.py b/rhodecode/apps/login/views.py --- a/rhodecode/apps/login/views.py +++ b/rhodecode/apps/login/views.py @@ -173,7 +173,7 @@ class LoginView(BaseAppView): ip_addr=self.request.remote_addr) action_data = {'user_agent': self.request.user_agent} audit_logger.store_web( - action='user.login.success', action_data=action_data, + 'user.login.success', action_data=action_data, user=audit_user, commit=True) raise HTTPFound(c.came_from, headers=headers) @@ -192,7 +192,7 @@ class LoginView(BaseAppView): ip_addr=self.request.remote_addr) action_data = {'user_agent': self.request.user_agent} audit_logger.store_web( - action='user.login.failure', action_data=action_data, + 'user.login.failure', action_data=action_data, user=audit_user, commit=True) return render_ctx @@ -212,7 +212,7 @@ class LoginView(BaseAppView): action_data = {'user_agent': self.request.user_agent} audit_logger.store_web( - action='user.logout', action_data=action_data, + 'user.logout', action_data=action_data, user=auth_user, commit=True) self.session.delete() return HTTPFound(h.route_path('home')) @@ -365,8 +365,7 @@ class LoginView(BaseAppView): action_data = {'email': user_email, 'user_agent': self.request.user_agent} audit_logger.store_web( - action='user.password.reset_request', - action_data=action_data, + 'user.password.reset_request', action_data=action_data, user=self._rhodecode_user, commit=True) return HTTPFound(self.request.route_path('reset_password')) diff --git a/rhodecode/apps/my_account/views.py b/rhodecode/apps/my_account/views.py --- a/rhodecode/apps/my_account/views.py +++ b/rhodecode/apps/my_account/views.py @@ -183,8 +183,8 @@ class MyAccountView(BaseAppView): self.maybe_attach_token_scope(token) audit_logger.store_web( - action='user.edit.token.add', - action_data={'data': {'token': token_data, 'user': 'self'}}, + 'user.edit.token.add', action_data={ + 'data': {'token': token_data, 'user': 'self'}}, user=self._rhodecode_user, ) Session().commit() @@ -208,8 +208,8 @@ class MyAccountView(BaseAppView): AuthTokenModel().delete(del_auth_token, c.user.user_id) audit_logger.store_web( - action='user.edit.token.delete', - action_data={'data': {'token': token_data, 'user': 'self'}}, + 'user.edit.token.delete', action_data={ + 'data': {'token': token_data, 'user': 'self'}}, user=self._rhodecode_user,) Session().commit() h.flash(_("Auth token successfully deleted"), category='success') @@ -245,8 +245,8 @@ class MyAccountView(BaseAppView): try: UserModel().add_extra_email(c.user.user_id, email) audit_logger.store_web( - action='user.edit.email.add', - action_data={'data': {'email': email, 'user': 'self'}}, + 'user.edit.email.add', action_data={ + 'data': {'email': email, 'user': 'self'}}, user=self._rhodecode_user,) Session().commit() @@ -274,8 +274,8 @@ class MyAccountView(BaseAppView): email = UserEmailMap.get_or_404(del_email_id, pyramid_exc=True).email UserModel().delete_extra_email(c.user.user_id, del_email_id) audit_logger.store_web( - action='user.edit.email.delete', - action_data={'data': {'email': email, 'user': 'self'}}, + 'user.edit.email.delete', action_data={ + 'data': {'email': email, 'user': 'self'}}, user=self._rhodecode_user,) Session().commit() h.flash(_("Email successfully deleted"), 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 @@ -95,14 +95,13 @@ class RepoSettingsView(RepoAppView): handle_forks = 'delete' h.flash(_('Deleted %s forks') % _forks, category='success') - repo_data = self.db_repo.get_api_data() + old_data = self.db_repo.get_api_data() RepoModel().delete(self.db_repo, forks=handle_forks) repo = audit_logger.RepoWrap(repo_id=None, repo_name=self.db_repo.repo_name) audit_logger.store_web( - action='repo.delete', - action_data={'data': repo_data}, + 'repo.delete', action_data={'old_data': old_data}, user=self._rhodecode_user, repo=repo) ScmModel().mark_for_invalidation(self.db_repo_name, delete=True) diff --git a/rhodecode/apps/repository/views/repo_strip.py b/rhodecode/apps/repository/views/repo_strip.py --- a/rhodecode/apps/repository/views/repo_strip.py +++ b/rhodecode/apps/repository/views/repo_strip.py @@ -106,10 +106,8 @@ class StripView(RepoAppView): data[commit['rev']] = True audit_logger.store_web( - action='repo.commit.strip', - action_data={'commit_id': commit['rev']}, - repo=self.db_repo, - user=self._rhodecode_user, commit=True) + 'repo.commit.strip', action_data={'commit_id': commit['rev']}, + repo=self.db_repo, user=self._rhodecode_user, commit=True) except Exception as e: data[commit['rev']] = False diff --git a/rhodecode/controllers/admin/repo_groups.py b/rhodecode/controllers/admin/repo_groups.py --- a/rhodecode/controllers/admin/repo_groups.py +++ b/rhodecode/controllers/admin/repo_groups.py @@ -185,14 +185,16 @@ class RepoGroupsController(BaseControlle owner=owner.user_id, copy_permissions=form_result['group_copy_permissions'] ) - Session().commit() - repo_group_data = repo_group.get_api_data() - _new_group_name = form_result['group_name_full'] + Session().flush() + repo_group_data = repo_group.get_api_data() audit_logger.store_web( - action='repo_group.create', - action_data={'data': repo_group_data}, - user=c.rhodecode_user, commit=True) + 'repo_group.create', action_data={'data': repo_group_data}, + user=c.rhodecode_user) + + Session().commit() + + _new_group_name = form_result['group_name_full'] repo_group_url = h.link_to( _new_group_name, @@ -304,8 +306,7 @@ class RepoGroupsController(BaseControlle RepoGroupModel().delete(group_name) audit_logger.store_web( - 'repo_group.delete', - action_data={'old_data': old_values}, + 'repo_group.delete', action_data={'old_data': old_values}, user=c.rhodecode_user) Session().commit() diff --git a/rhodecode/controllers/admin/user_groups.py b/rhodecode/controllers/admin/user_groups.py --- a/rhodecode/controllers/admin/user_groups.py +++ b/rhodecode/controllers/admin/user_groups.py @@ -205,13 +205,16 @@ class UserGroupsController(BaseControlle pstruct = peppercorn.parse(request.POST.items()) form_result['users_group_members'] = pstruct['user_group_members'] - UserGroupModel().update(c.user_group, form_result) + user_group, added_members, removed_members = \ + UserGroupModel().update(c.user_group, form_result) updated_user_group = form_result['users_group_name'] audit_logger.store_web( 'user_group.edit', action_data={'old_data': old_values}, user=c.rhodecode_user) + # TODO(marcink): use added/removed to set user_group.edit.member.add + h.flash(_('Updated user group %s') % updated_user_group, category='success') Session().commit() diff --git a/rhodecode/controllers/files.py b/rhodecode/controllers/files.py --- a/rhodecode/controllers/files.py +++ b/rhodecode/controllers/files.py @@ -815,11 +815,11 @@ class FilesController(BaseRepoController # store download action audit_logger.store_web( - action='repo.archive.download', - action_data={'user_agent': request.user_agent, - 'archive_name': archive_name, - 'archive_spec': fname, - 'archive_cached': use_cached_archive}, + 'repo.archive.download', action_data={ + 'user_agent': request.user_agent, + 'archive_name': archive_name, + 'archive_spec': fname, + 'archive_cached': use_cached_archive}, user=c.rhodecode_user, repo=dbrepo, commit=True diff --git a/rhodecode/lib/audit_logger.py b/rhodecode/lib/audit_logger.py --- a/rhodecode/lib/audit_logger.py +++ b/rhodecode/lib/audit_logger.py @@ -53,8 +53,8 @@ ACTIONS_V1 = { 'user_group.delete': {'old_data': {}}, 'user_group.edit': {'old_data': {}}, 'user_group.edit.permissions': {}, - 'user_group.edit.member.add': {}, - 'user_group.edit.member.delete': {}, + 'user_group.edit.member.add': {'user': {}}, + 'user_group.edit.member.delete': {'user': {}}, 'repo.create': {'data': {}}, 'repo.fork': {'data': {}}, @@ -76,8 +76,8 @@ ACTIONS_V1 = { 'repo.pull_request.reviewer.add': '', 'repo.pull_request.reviewer.delete': '', - 'repo.commit.comment.create': '', - 'repo.commit.comment.delete': '', + 'repo.commit.comment.create': {'data': {}}, + 'repo.commit.comment.delete': {'data': {}}, 'repo.commit.vote': '', 'repo_group.create': {'data': {}}, @@ -164,34 +164,32 @@ def store(action, user, action_data=None from rhodecode.lib import audit_logger audit_logger.store( - action='repo.edit', user=self._rhodecode_user) + 'repo.edit', user=self._rhodecode_user) audit_logger.store( - action='repo.delete', action_data={'data': repo_data}, + 'repo.delete', action_data={'data': repo_data}, user=audit_logger.UserWrap(username='itried-login', ip_addr='8.8.8.8')) # repo action audit_logger.store( - action='repo.delete', + 'repo.delete', user=audit_logger.UserWrap(username='itried-login', ip_addr='8.8.8.8'), repo=audit_logger.RepoWrap(repo_name='some-repo')) # repo action, when we know and have the repository object already audit_logger.store( - action='repo.delete', - action_data={'source': audit_logger.SOURCE_WEB, }, + 'repo.delete', action_data={'source': audit_logger.SOURCE_WEB, }, user=self._rhodecode_user, repo=repo_object) # alternative wrapper to the above audit_logger.store_web( - action='repo.delete', - action_data={}, + 'repo.delete', action_data={}, user=self._rhodecode_user, repo=repo_object) # without an user ? audit_logger.store( - action='user.login.failure', + 'user.login.failure', user=audit_logger.UserWrap( username=self.request.params.get('username'), ip_addr=self.request.remote_addr)) diff --git a/rhodecode/lib/celerylib/tasks.py b/rhodecode/lib/celerylib/tasks.py --- a/rhodecode/lib/celerylib/tasks.py +++ b/rhodecode/lib/celerylib/tasks.py @@ -179,9 +179,8 @@ def create_repo(form_data, cur_user): repo_id = repo.repo_id repo_data = repo.get_api_data() - audit_logger.store_web( - action='repo.create', - action_data={'data': repo_data}, + audit_logger.store( + 'repo.create', action_data={'data': repo_data}, user=cur_user, repo=audit_logger.RepoWrap(repo_name=repo_name, repo_id=repo_id)) @@ -274,9 +273,8 @@ def create_repo_fork(form_data, cur_user repo_id = repo.repo_id repo_data = repo.get_api_data() - audit_logger.store_web( - action='repo.fork', - action_data={'data': repo_data}, + audit_logger.store( + 'repo.fork', action_data={'data': repo_data}, user=cur_user, repo=audit_logger.RepoWrap(repo_name=repo_name, repo_id=repo_id)) diff --git a/rhodecode/lib/hooks_base.py b/rhodecode/lib/hooks_base.py --- a/rhodecode/lib/hooks_base.py +++ b/rhodecode/lib/hooks_base.py @@ -158,7 +158,7 @@ def post_pull(extras): ip_addr=extras.ip) repo = audit_logger.RepoWrap(repo_name=extras.repository) audit_logger.store( - action='user.pull', action_data={ + 'user.pull', action_data={ 'user_agent': extras.user_agent}, user=audit_user, repo=repo, commit=True) @@ -199,7 +199,7 @@ def post_push(extras): username=extras.username, ip_addr=extras.ip) repo = audit_logger.RepoWrap(repo_name=extras.repository) audit_logger.store( - action='user.push', action_data={ + 'user.push', action_data={ 'user_agent': extras.user_agent, 'commit_ids': commit_ids[:10000]}, user=audit_user, repo=repo, commit=True) diff --git a/rhodecode/model/user_group.py b/rhodecode/model/user_group.py --- a/rhodecode/model/user_group.py +++ b/rhodecode/model/user_group.py @@ -175,7 +175,7 @@ class UserGroupModel(BaseModel): user_id for user_id in current_members_ids if user_id not in user_id_list] - return (added_members, deleted_members) + return added_members, deleted_members def _set_users_as_members(self, user_group, user_ids): user_group.members = [] @@ -191,6 +191,7 @@ class UserGroupModel(BaseModel): self._set_users_as_members(user_group, user_ids) self._log_user_changes('added to', user_group, added) self._log_user_changes('removed from', user_group, removed) + return added, removed def _clean_members_data(self, members_data): if not members_data: @@ -225,12 +226,16 @@ class UserGroupModel(BaseModel): user_group.user = owner + added_user_ids = [] + removed_user_ids = [] if 'users_group_members' in form_data: members_id_list = self._clean_members_data( form_data['users_group_members']) - self._update_members_from_user_ids(user_group, members_id_list) + added_user_ids, removed_user_ids = \ + self._update_members_from_user_ids(user_group, members_id_list) self.sa.add(user_group) + return user_group, added_user_ids, removed_user_ids def delete(self, user_group, force=False): """