##// END OF EJS Templates
audit-logs: added audit-logs on user actions....
marcink -
r1801:c1a16410 default
parent child Browse files
Show More
@@ -31,15 +31,17 b' from pylons.controllers.util import redi'
31 from pylons.i18n.translation import _
31 from pylons.i18n.translation import _
32
32
33 from rhodecode.authentication.plugins import auth_rhodecode
33 from rhodecode.authentication.plugins import auth_rhodecode
34
35 from rhodecode.lib import helpers as h
36 from rhodecode.lib import auth
37 from rhodecode.lib import audit_logger
38 from rhodecode.lib.auth import (
39 LoginRequired, HasPermissionAllDecorator, AuthUser)
40 from rhodecode.lib.base import BaseController, render
34 from rhodecode.lib.exceptions import (
41 from rhodecode.lib.exceptions import (
35 DefaultUserException, UserOwnsReposException, UserOwnsRepoGroupsException,
42 DefaultUserException, UserOwnsReposException, UserOwnsRepoGroupsException,
36 UserOwnsUserGroupsException, UserCreationError)
43 UserOwnsUserGroupsException, UserCreationError)
37 from rhodecode.lib import helpers as h
44 from rhodecode.lib.utils2 import safe_int, AttributeDict
38 from rhodecode.lib import auth
39 from rhodecode.lib.auth import (
40 LoginRequired, HasPermissionAllDecorator, AuthUser, generate_auth_token)
41 from rhodecode.lib.base import BaseController, render
42 from rhodecode.model.auth_token import AuthTokenModel
43
45
44 from rhodecode.model.db import (
46 from rhodecode.model.db import (
45 PullRequestReviewers, User, UserEmailMap, UserIpMap, RepoGroup)
47 PullRequestReviewers, User, UserEmailMap, UserIpMap, RepoGroup)
@@ -49,8 +51,6 b' from rhodecode.model.repo_group import R'
49 from rhodecode.model.user import UserModel
51 from rhodecode.model.user import UserModel
50 from rhodecode.model.meta import Session
52 from rhodecode.model.meta import Session
51 from rhodecode.model.permission import PermissionModel
53 from rhodecode.model.permission import PermissionModel
52 from rhodecode.lib.utils import action_logger
53 from rhodecode.lib.utils2 import datetime_to_time, safe_int, AttributeDict
54
54
55 log = logging.getLogger(__name__)
55 log = logging.getLogger(__name__)
56
56
@@ -88,7 +88,6 b' class UsersController(BaseController):'
88 @HasPermissionAllDecorator('hg.admin')
88 @HasPermissionAllDecorator('hg.admin')
89 @auth.CSRFRequired()
89 @auth.CSRFRequired()
90 def create(self):
90 def create(self):
91 """POST /users: Create a new item"""
92 c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.name
91 c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.name
93 user_model = UserModel()
92 user_model = UserModel()
94 user_form = UserForm()()
93 user_form = UserForm()()
@@ -96,9 +95,12 b' class UsersController(BaseController):'
96 form_result = user_form.to_python(dict(request.POST))
95 form_result = user_form.to_python(dict(request.POST))
97 user = user_model.create(form_result)
96 user = user_model.create(form_result)
98 Session().flush()
97 Session().flush()
98 creation_data = user.get_api_data()
99 username = form_result['username']
99 username = form_result['username']
100 action_logger(c.rhodecode_user, 'admin_created_user:%s' % username,
100
101 None, self.ip_addr, self.sa)
101 audit_logger.store_web(
102 'user.create', action_data={'data': creation_data},
103 user=c.rhodecode_user)
102
104
103 user_link = h.link_to(h.escape(username),
105 user_link = h.link_to(h.escape(username),
104 url('edit_user',
106 url('edit_user',
@@ -125,8 +127,6 b' class UsersController(BaseController):'
125
127
126 @HasPermissionAllDecorator('hg.admin')
128 @HasPermissionAllDecorator('hg.admin')
127 def new(self):
129 def new(self):
128 """GET /users/new: Form to create a new item"""
129 # url('new_user')
130 c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.name
130 c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.name
131 self._get_personal_repo_group_template_vars()
131 self._get_personal_repo_group_template_vars()
132 return render('admin/users/user_add.mako')
132 return render('admin/users/user_add.mako')
@@ -134,13 +134,7 b' class UsersController(BaseController):'
134 @HasPermissionAllDecorator('hg.admin')
134 @HasPermissionAllDecorator('hg.admin')
135 @auth.CSRFRequired()
135 @auth.CSRFRequired()
136 def update(self, user_id):
136 def update(self, user_id):
137 """PUT /users/user_id: Update an existing item"""
137
138 # Forms posted to this method should contain a hidden field:
139 # <input type="hidden" name="_method" value="PUT" />
140 # Or using helpers:
141 # h.form(url('update_user', user_id=ID),
142 # method='put')
143 # url('user', user_id=ID)
144 user_id = safe_int(user_id)
138 user_id = safe_int(user_id)
145 c.user = User.get_or_404(user_id)
139 c.user = User.get_or_404(user_id)
146 c.active = 'profile'
140 c.active = 'profile'
@@ -152,6 +146,7 b' class UsersController(BaseController):'
152 old_data={'user_id': user_id,
146 old_data={'user_id': user_id,
153 'email': c.user.email})()
147 'email': c.user.email})()
154 form_result = {}
148 form_result = {}
149 old_values = c.user.get_api_data()
155 try:
150 try:
156 form_result = _form.to_python(dict(request.POST))
151 form_result = _form.to_python(dict(request.POST))
157 skip_attrs = ['extern_type', 'extern_name']
152 skip_attrs = ['extern_type', 'extern_name']
@@ -160,12 +155,15 b' class UsersController(BaseController):'
160 # forbid updating username for external accounts
155 # forbid updating username for external accounts
161 skip_attrs.append('username')
156 skip_attrs.append('username')
162
157
163 UserModel().update_user(user_id, skip_attrs=skip_attrs, **form_result)
158 UserModel().update_user(
164 usr = form_result['username']
159 user_id, skip_attrs=skip_attrs, **form_result)
165 action_logger(c.rhodecode_user, 'admin_updated_user:%s' % usr,
160
166 None, self.ip_addr, self.sa)
161 audit_logger.store_web(
162 'user.edit', action_data={'old_data': old_values},
163 user=c.rhodecode_user)
164
165 Session().commit()
167 h.flash(_('User updated successfully'), category='success')
166 h.flash(_('User updated successfully'), category='success')
168 Session().commit()
169 except formencode.Invalid as errors:
167 except formencode.Invalid as errors:
170 defaults = errors.value
168 defaults = errors.value
171 e = errors.error_dict or {}
169 e = errors.error_dict or {}
@@ -188,13 +186,6 b' class UsersController(BaseController):'
188 @HasPermissionAllDecorator('hg.admin')
186 @HasPermissionAllDecorator('hg.admin')
189 @auth.CSRFRequired()
187 @auth.CSRFRequired()
190 def delete(self, user_id):
188 def delete(self, user_id):
191 """DELETE /users/user_id: Delete an existing item"""
192 # Forms posted to this method should contain a hidden field:
193 # <input type="hidden" name="_method" value="DELETE" />
194 # Or using helpers:
195 # h.form(url('delete_user', user_id=ID),
196 # method='delete')
197 # url('user', user_id=ID)
198 user_id = safe_int(user_id)
189 user_id = safe_int(user_id)
199 c.user = User.get_or_404(user_id)
190 c.user = User.get_or_404(user_id)
200
191
@@ -249,10 +240,16 b' class UsersController(BaseController):'
249 _('Deleted %s user groups') % len(_user_groups),
240 _('Deleted %s user groups') % len(_user_groups),
250 category='success')
241 category='success')
251
242
243 old_values = c.user.get_api_data()
252 try:
244 try:
253 UserModel().delete(c.user, handle_repos=handle_repos,
245 UserModel().delete(c.user, handle_repos=handle_repos,
254 handle_repo_groups=handle_repo_groups,
246 handle_repo_groups=handle_repo_groups,
255 handle_user_groups=handle_user_groups)
247 handle_user_groups=handle_user_groups)
248
249 audit_logger.store_web(
250 'user.delete', action_data={'old_data': old_values},
251 user=c.rhodecode_user)
252
256 Session().commit()
253 Session().commit()
257 set_handle_flash_repos()
254 set_handle_flash_repos()
258 set_handle_flash_repo_groups()
255 set_handle_flash_repo_groups()
@@ -272,19 +269,25 b' class UsersController(BaseController):'
272 def reset_password(self, user_id):
269 def reset_password(self, user_id):
273 """
270 """
274 toggle reset password flag for this user
271 toggle reset password flag for this user
275
276 :param user_id:
277 """
272 """
278 user_id = safe_int(user_id)
273 user_id = safe_int(user_id)
279 c.user = User.get_or_404(user_id)
274 c.user = User.get_or_404(user_id)
280 try:
275 try:
281 old_value = c.user.user_data.get('force_password_change')
276 old_value = c.user.user_data.get('force_password_change')
282 c.user.update_userdata(force_password_change=not old_value)
277 c.user.update_userdata(force_password_change=not old_value)
283 Session().commit()
278
284 if old_value:
279 if old_value:
285 msg = _('Force password change disabled for user')
280 msg = _('Force password change disabled for user')
281 audit_logger.store_web(
282 'user.edit.password_reset.disabled',
283 user=c.rhodecode_user)
286 else:
284 else:
287 msg = _('Force password change enabled for user')
285 msg = _('Force password change enabled for user')
286 audit_logger.store_web(
287 'user.edit.password_reset.enabled',
288 user=c.rhodecode_user)
289
290 Session().commit()
288 h.flash(msg, category='success')
291 h.flash(msg, category='success')
289 except Exception:
292 except Exception:
290 log.exception("Exception during password reset for user")
293 log.exception("Exception during password reset for user")
@@ -298,8 +301,6 b' class UsersController(BaseController):'
298 def create_personal_repo_group(self, user_id):
301 def create_personal_repo_group(self, user_id):
299 """
302 """
300 Create personal repository group for this user
303 Create personal repository group for this user
301
302 :param user_id:
303 """
304 """
304 from rhodecode.model.repo_group import RepoGroupModel
305 from rhodecode.model.repo_group import RepoGroupModel
305
306
@@ -428,8 +429,6 b' class UsersController(BaseController):'
428 @HasPermissionAllDecorator('hg.admin')
429 @HasPermissionAllDecorator('hg.admin')
429 @auth.CSRFRequired()
430 @auth.CSRFRequired()
430 def update_global_perms(self, user_id):
431 def update_global_perms(self, user_id):
431 """PUT /users_perm/user_id: Update an existing item"""
432 # url('user_perm', user_id=ID, method='put')
433 user_id = safe_int(user_id)
432 user_id = safe_int(user_id)
434 user = User.get_or_404(user_id)
433 user = User.get_or_404(user_id)
435 c.active = 'global_perms'
434 c.active = 'global_perms'
@@ -456,11 +455,13 b' class UsersController(BaseController):'
456
455
457 PermissionModel().update_user_permissions(form_result)
456 PermissionModel().update_user_permissions(form_result)
458
457
458 # TODO(marcink): implement global permissions
459 # audit_log.store_web('user.edit.permissions')
460
459 Session().commit()
461 Session().commit()
460 h.flash(_('User global permissions updated successfully'),
462 h.flash(_('User global permissions updated successfully'),
461 category='success')
463 category='success')
462
464
463 Session().commit()
464 except formencode.Invalid as errors:
465 except formencode.Invalid as errors:
465 defaults = errors.value
466 defaults = errors.value
466 c.user = user
467 c.user = user
@@ -512,16 +513,18 b' class UsersController(BaseController):'
512 @HasPermissionAllDecorator('hg.admin')
513 @HasPermissionAllDecorator('hg.admin')
513 @auth.CSRFRequired()
514 @auth.CSRFRequired()
514 def add_email(self, user_id):
515 def add_email(self, user_id):
515 """POST /user_emails:Add an existing item"""
516 # url('user_emails', user_id=ID, method='put')
517 user_id = safe_int(user_id)
516 user_id = safe_int(user_id)
518 c.user = User.get_or_404(user_id)
517 c.user = User.get_or_404(user_id)
519
518
520 email = request.POST.get('new_email')
519 email = request.POST.get('new_email')
521 user_model = UserModel()
520 user_model = UserModel()
522
521 user_data = c.user.get_api_data()
523 try:
522 try:
524 user_model.add_extra_email(user_id, email)
523 user_model.add_extra_email(user_id, email)
524 audit_logger.store_web(
525 'user.edit.email.add',
526 action_data={'email': email, 'user': user_data},
527 user=c.rhodecode_user)
525 Session().commit()
528 Session().commit()
526 h.flash(_("Added new email address `%s` for user account") % email,
529 h.flash(_("Added new email address `%s` for user account") % email,
527 category='success')
530 category='success')
@@ -537,13 +540,18 b' class UsersController(BaseController):'
537 @HasPermissionAllDecorator('hg.admin')
540 @HasPermissionAllDecorator('hg.admin')
538 @auth.CSRFRequired()
541 @auth.CSRFRequired()
539 def delete_email(self, user_id):
542 def delete_email(self, user_id):
540 """DELETE /user_emails_delete/user_id: Delete an existing item"""
541 # url('user_emails_delete', user_id=ID, method='delete')
542 user_id = safe_int(user_id)
543 user_id = safe_int(user_id)
543 c.user = User.get_or_404(user_id)
544 c.user = User.get_or_404(user_id)
544 email_id = request.POST.get('del_email_id')
545 email_id = request.POST.get('del_email_id')
545 user_model = UserModel()
546 user_model = UserModel()
547
548 email = UserEmailMap.query().get(email_id).email
549 user_data = c.user.get_api_data()
546 user_model.delete_extra_email(user_id, email_id)
550 user_model.delete_extra_email(user_id, email_id)
551 audit_logger.store_web(
552 'user.edit.email.delete',
553 action_data={'email': email, 'user': user_data},
554 user=c.rhodecode_user)
547 Session().commit()
555 Session().commit()
548 h.flash(_("Removed email address from user account"), category='success')
556 h.flash(_("Removed email address from user account"), category='success')
549 return redirect(url('edit_user_emails', user_id=user_id))
557 return redirect(url('edit_user_emails', user_id=user_id))
@@ -574,9 +582,6 b' class UsersController(BaseController):'
574 @HasPermissionAllDecorator('hg.admin')
582 @HasPermissionAllDecorator('hg.admin')
575 @auth.CSRFRequired()
583 @auth.CSRFRequired()
576 def add_ip(self, user_id):
584 def add_ip(self, user_id):
577 """POST /user_ips:Add an existing item"""
578 # url('user_ips', user_id=ID, method='put')
579
580 user_id = safe_int(user_id)
585 user_id = safe_int(user_id)
581 c.user = User.get_or_404(user_id)
586 c.user = User.get_or_404(user_id)
582 user_model = UserModel()
587 user_model = UserModel()
@@ -590,9 +595,14 b' class UsersController(BaseController):'
590
595
591 desc = request.POST.get('description')
596 desc = request.POST.get('description')
592 added = []
597 added = []
598 user_data = c.user.get_api_data()
593 for ip in ip_list:
599 for ip in ip_list:
594 try:
600 try:
595 user_model.add_extra_ip(user_id, ip, desc)
601 user_model.add_extra_ip(user_id, ip, desc)
602 audit_logger.store_web(
603 'user.edit.ip.add',
604 action_data={'ip': ip, 'user': user_data},
605 user=c.rhodecode_user)
596 Session().commit()
606 Session().commit()
597 added.append(ip)
607 added.append(ip)
598 except formencode.Invalid as error:
608 except formencode.Invalid as error:
@@ -613,14 +623,18 b' class UsersController(BaseController):'
613 @HasPermissionAllDecorator('hg.admin')
623 @HasPermissionAllDecorator('hg.admin')
614 @auth.CSRFRequired()
624 @auth.CSRFRequired()
615 def delete_ip(self, user_id):
625 def delete_ip(self, user_id):
616 """DELETE /user_ips_delete/user_id: Delete an existing item"""
617 # url('user_ips_delete', user_id=ID, method='delete')
618 user_id = safe_int(user_id)
626 user_id = safe_int(user_id)
619 c.user = User.get_or_404(user_id)
627 c.user = User.get_or_404(user_id)
620
628
621 ip_id = request.POST.get('del_ip_id')
629 ip_id = request.POST.get('del_ip_id')
622 user_model = UserModel()
630 user_model = UserModel()
631 ip = UserIpMap.query().get(ip_id).ip_addr
632 user_data = c.user.get_api_data()
623 user_model.delete_extra_ip(user_id, ip_id)
633 user_model.delete_extra_ip(user_id, ip_id)
634 audit_logger.store_web(
635 'user.edit.ip.delete',
636 action_data={'ip': ip, 'user': user_data},
637 user=c.rhodecode_user)
624 Session().commit()
638 Session().commit()
625 h.flash(_("Removed ip address from user whitelist"), category='success')
639 h.flash(_("Removed ip address from user whitelist"), category='success')
626
640
@@ -27,7 +27,7 b' from rhodecode.model.db import User, Use'
27
27
28 log = logging.getLogger(__name__)
28 log = logging.getLogger(__name__)
29
29
30
30 # action as key, and expected action_data as value
31 ACTIONS = {
31 ACTIONS = {
32 'user.login.success': {},
32 'user.login.success': {},
33 'user.login.failure': {},
33 'user.login.failure': {},
@@ -38,6 +38,19 b' ACTIONS = {'
38
38
39 'repo.create': {},
39 'repo.create': {},
40 'repo.edit': {},
40 'repo.edit': {},
41 'user.create': {'data': {}},
42 'user.delete': {'old_data': {}},
43 'user.edit': {'old_data': {}},
44 'user.edit.permissions': {},
45 'user.edit.ip.add': {},
46 'user.edit.ip.delete': {},
47 'user.edit.token.add': {},
48 'user.edit.token.delete': {},
49 'user.edit.email.add': {},
50 'user.edit.email.delete': {},
51 'user.edit.password_reset.enabled': {},
52 'user.edit.password_reset.disabled': {},
53
41 'repo.edit.permissions': {},
54 'repo.edit.permissions': {},
42 'repo.delete': {},
55 'repo.delete': {},
43 'repo.commit.strip': {},
56 'repo.commit.strip': {},
@@ -117,9 +130,8 b' def store_api(*args, **kwargs):'
117 return store(*args, **kwargs)
130 return store(*args, **kwargs)
118
131
119
132
120 def store(
133 def store(action, user, action_data=None, user_data=None, ip_addr=None,
121 action, user, action_data=None, user_data=None, ip_addr=None,
134 repo=None, sa_session=None, commit=False):
122 repo=None, sa_session=None, commit=False):
123 """
135 """
124 Audit logger for various actions made by users, typically this
136 Audit logger for various actions made by users, typically this
125 results in a call such::
137 results in a call such::
@@ -767,7 +767,7 b' class UserModel(BaseModel):'
767 """
767 """
768 user = self._get_user(user)
768 user = self._get_user(user)
769 obj = UserEmailMap.query().get(email_id)
769 obj = UserEmailMap.query().get(email_id)
770 if obj:
770 if obj and obj.user_id == user.user_id:
771 self.sa.delete(obj)
771 self.sa.delete(obj)
772
772
773 def parse_ip_range(self, ip_range):
773 def parse_ip_range(self, ip_range):
@@ -824,7 +824,7 b' class UserModel(BaseModel):'
824 """
824 """
825 user = self._get_user(user)
825 user = self._get_user(user)
826 obj = UserIpMap.query().get(ip_id)
826 obj = UserIpMap.query().get(ip_id)
827 if obj:
827 if obj and obj.user_id == user.user_id:
828 self.sa.delete(obj)
828 self.sa.delete(obj)
829
829
830 def get_accounts_in_creation_order(self, current_user=None):
830 def get_accounts_in_creation_order(self, current_user=None):
General Comments 0
You need to be logged in to leave comments. Login now