##// END OF EJS Templates
audit-logs: added audit logs on user groups admin page.
marcink -
r1805:48072a57 default
parent child Browse files
Show More
@@ -1,517 +1,510 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2017 RhodeCode GmbH
3 # Copyright (C) 2011-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 """
21 """
22 User Groups crud controller for pylons
22 User Groups crud controller for pylons
23 """
23 """
24
24
25 import logging
25 import logging
26 import formencode
26 import formencode
27
27
28 import peppercorn
28 import peppercorn
29 from formencode import htmlfill
29 from formencode import htmlfill
30 from pylons import request, tmpl_context as c, url, config
30 from pylons import request, tmpl_context as c, url, config
31 from pylons.controllers.util import redirect
31 from pylons.controllers.util import redirect
32 from pylons.i18n.translation import _
32 from pylons.i18n.translation import _
33
33
34 from sqlalchemy.orm import joinedload
34 from sqlalchemy.orm import joinedload
35
35
36 from rhodecode.lib import auth
36 from rhodecode.lib import auth
37 from rhodecode.lib import helpers as h
37 from rhodecode.lib import helpers as h
38 from rhodecode.lib import audit_logger
38 from rhodecode.lib.ext_json import json
39 from rhodecode.lib.ext_json import json
39 from rhodecode.lib.exceptions import UserGroupAssignedException,\
40 from rhodecode.lib.exceptions import UserGroupAssignedException,\
40 RepoGroupAssignmentError
41 RepoGroupAssignmentError
41 from rhodecode.lib.utils import jsonify, action_logger
42 from rhodecode.lib.utils import jsonify
42 from rhodecode.lib.utils2 import safe_unicode, str2bool, safe_int
43 from rhodecode.lib.utils2 import safe_unicode, str2bool, safe_int
43 from rhodecode.lib.auth import (
44 from rhodecode.lib.auth import (
44 LoginRequired, NotAnonymous, HasUserGroupPermissionAnyDecorator,
45 LoginRequired, NotAnonymous, HasUserGroupPermissionAnyDecorator,
45 HasPermissionAnyDecorator, XHRRequired)
46 HasPermissionAnyDecorator, XHRRequired)
46 from rhodecode.lib.base import BaseController, render
47 from rhodecode.lib.base import BaseController, render
47 from rhodecode.model.permission import PermissionModel
48 from rhodecode.model.permission import PermissionModel
48 from rhodecode.model.scm import UserGroupList
49 from rhodecode.model.scm import UserGroupList
49 from rhodecode.model.user_group import UserGroupModel
50 from rhodecode.model.user_group import UserGroupModel
50 from rhodecode.model.db import (
51 from rhodecode.model.db import (
51 User, UserGroup, UserGroupRepoToPerm, UserGroupRepoGroupToPerm)
52 User, UserGroup, UserGroupRepoToPerm, UserGroupRepoGroupToPerm)
52 from rhodecode.model.forms import (
53 from rhodecode.model.forms import (
53 UserGroupForm, UserGroupPermsForm, UserIndividualPermissionsForm,
54 UserGroupForm, UserGroupPermsForm, UserIndividualPermissionsForm,
54 UserPermissionsForm)
55 UserPermissionsForm)
55 from rhodecode.model.meta import Session
56 from rhodecode.model.meta import Session
56
57
57
58
58 log = logging.getLogger(__name__)
59 log = logging.getLogger(__name__)
59
60
60
61
61 class UserGroupsController(BaseController):
62 class UserGroupsController(BaseController):
62 """REST Controller styled on the Atom Publishing Protocol"""
63 """REST Controller styled on the Atom Publishing Protocol"""
63
64
64 @LoginRequired()
65 @LoginRequired()
65 def __before__(self):
66 def __before__(self):
66 super(UserGroupsController, self).__before__()
67 super(UserGroupsController, self).__before__()
67 c.available_permissions = config['available_permissions']
68 c.available_permissions = config['available_permissions']
68 PermissionModel().set_global_permission_choices(c, gettext_translator=_)
69 PermissionModel().set_global_permission_choices(c, gettext_translator=_)
69
70
70 def __load_data(self, user_group_id):
71 def __load_data(self, user_group_id):
71 c.group_members_obj = [x.user for x in c.user_group.members]
72 c.group_members_obj = [x.user for x in c.user_group.members]
72 c.group_members_obj.sort(key=lambda u: u.username.lower())
73 c.group_members_obj.sort(key=lambda u: u.username.lower())
73 c.group_members = [(x.user_id, x.username) for x in c.group_members_obj]
74 c.group_members = [(x.user_id, x.username) for x in c.group_members_obj]
74
75
75 def __load_defaults(self, user_group_id):
76 def __load_defaults(self, user_group_id):
76 """
77 """
77 Load defaults settings for edit, and update
78 Load defaults settings for edit, and update
78
79
79 :param user_group_id:
80 :param user_group_id:
80 """
81 """
81 user_group = UserGroup.get_or_404(user_group_id)
82 user_group = UserGroup.get_or_404(user_group_id)
82 data = user_group.get_dict()
83 data = user_group.get_dict()
83 # fill owner
84 # fill owner
84 if user_group.user:
85 if user_group.user:
85 data.update({'user': user_group.user.username})
86 data.update({'user': user_group.user.username})
86 else:
87 else:
87 replacement_user = User.get_first_super_admin().username
88 replacement_user = User.get_first_super_admin().username
88 data.update({'user': replacement_user})
89 data.update({'user': replacement_user})
89 return data
90 return data
90
91
91 def _revoke_perms_on_yourself(self, form_result):
92 def _revoke_perms_on_yourself(self, form_result):
92 _updates = filter(lambda u: c.rhodecode_user.user_id == int(u[0]),
93 _updates = filter(lambda u: c.rhodecode_user.user_id == int(u[0]),
93 form_result['perm_updates'])
94 form_result['perm_updates'])
94 _additions = filter(lambda u: c.rhodecode_user.user_id == int(u[0]),
95 _additions = filter(lambda u: c.rhodecode_user.user_id == int(u[0]),
95 form_result['perm_additions'])
96 form_result['perm_additions'])
96 _deletions = filter(lambda u: c.rhodecode_user.user_id == int(u[0]),
97 _deletions = filter(lambda u: c.rhodecode_user.user_id == int(u[0]),
97 form_result['perm_deletions'])
98 form_result['perm_deletions'])
98 admin_perm = 'usergroup.admin'
99 admin_perm = 'usergroup.admin'
99 if _updates and _updates[0][1] != admin_perm or \
100 if _updates and _updates[0][1] != admin_perm or \
100 _additions and _additions[0][1] != admin_perm or \
101 _additions and _additions[0][1] != admin_perm or \
101 _deletions and _deletions[0][1] != admin_perm:
102 _deletions and _deletions[0][1] != admin_perm:
102 return True
103 return True
103 return False
104 return False
104
105
105 # permission check inside
106 # permission check inside
106 @NotAnonymous()
107 @NotAnonymous()
107 def index(self):
108 def index(self):
108 """GET /users_groups: All items in the collection"""
109 # url('users_groups')
110
109
111 from rhodecode.lib.utils import PartialRenderer
110 from rhodecode.lib.utils import PartialRenderer
112 _render = PartialRenderer('data_table/_dt_elements.mako')
111 _render = PartialRenderer('data_table/_dt_elements.mako')
113
112
114 def user_group_name(user_group_id, user_group_name):
113 def user_group_name(user_group_id, user_group_name):
115 return _render("user_group_name", user_group_id, user_group_name)
114 return _render("user_group_name", user_group_id, user_group_name)
116
115
117 def user_group_actions(user_group_id, user_group_name):
116 def user_group_actions(user_group_id, user_group_name):
118 return _render("user_group_actions", user_group_id, user_group_name)
117 return _render("user_group_actions", user_group_id, user_group_name)
119
118
120 # json generate
119 # json generate
121 group_iter = UserGroupList(UserGroup.query().all(),
120 group_iter = UserGroupList(UserGroup.query().all(),
122 perm_set=['usergroup.admin'])
121 perm_set=['usergroup.admin'])
123
122
124 user_groups_data = []
123 user_groups_data = []
125 for user_gr in group_iter:
124 for user_gr in group_iter:
126 user_groups_data.append({
125 user_groups_data.append({
127 "group_name": user_group_name(
126 "group_name": user_group_name(
128 user_gr.users_group_id, h.escape(user_gr.users_group_name)),
127 user_gr.users_group_id, h.escape(user_gr.users_group_name)),
129 "group_name_raw": user_gr.users_group_name,
128 "group_name_raw": user_gr.users_group_name,
130 "desc": h.escape(user_gr.user_group_description),
129 "desc": h.escape(user_gr.user_group_description),
131 "members": len(user_gr.members),
130 "members": len(user_gr.members),
132 "sync": user_gr.group_data.get('extern_type'),
131 "sync": user_gr.group_data.get('extern_type'),
133 "active": h.bool2icon(user_gr.users_group_active),
132 "active": h.bool2icon(user_gr.users_group_active),
134 "owner": h.escape(h.link_to_user(user_gr.user.username)),
133 "owner": h.escape(h.link_to_user(user_gr.user.username)),
135 "action": user_group_actions(
134 "action": user_group_actions(
136 user_gr.users_group_id, user_gr.users_group_name)
135 user_gr.users_group_id, user_gr.users_group_name)
137 })
136 })
138
137
139 c.data = json.dumps(user_groups_data)
138 c.data = json.dumps(user_groups_data)
140 return render('admin/user_groups/user_groups.mako')
139 return render('admin/user_groups/user_groups.mako')
141
140
142 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
141 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
143 @auth.CSRFRequired()
142 @auth.CSRFRequired()
144 def create(self):
143 def create(self):
145 """POST /users_groups: Create a new item"""
146 # url('users_groups')
147
144
148 users_group_form = UserGroupForm()()
145 users_group_form = UserGroupForm()()
149 try:
146 try:
150 form_result = users_group_form.to_python(dict(request.POST))
147 form_result = users_group_form.to_python(dict(request.POST))
151 user_group = UserGroupModel().create(
148 user_group = UserGroupModel().create(
152 name=form_result['users_group_name'],
149 name=form_result['users_group_name'],
153 description=form_result['user_group_description'],
150 description=form_result['user_group_description'],
154 owner=c.rhodecode_user.user_id,
151 owner=c.rhodecode_user.user_id,
155 active=form_result['users_group_active'])
152 active=form_result['users_group_active'])
156 Session().flush()
153 Session().flush()
157
154 creation_data = user_group.get_api_data()
158 user_group_name = form_result['users_group_name']
155 user_group_name = form_result['users_group_name']
159 action_logger(c.rhodecode_user,
156
160 'admin_created_users_group:%s' % user_group_name,
157 audit_logger.store_web(
161 None, self.ip_addr, self.sa)
158 'user_group.create', action_data={'data': creation_data},
162 user_group_link = h.link_to(h.escape(user_group_name),
159 user=c.rhodecode_user)
163 url('edit_users_group',
160
164 user_group_id=user_group.users_group_id))
161 user_group_link = h.link_to(
162 h.escape(user_group_name),
163 url('edit_users_group', user_group_id=user_group.users_group_id))
165 h.flash(h.literal(_('Created user group %(user_group_link)s')
164 h.flash(h.literal(_('Created user group %(user_group_link)s')
166 % {'user_group_link': user_group_link}),
165 % {'user_group_link': user_group_link}),
167 category='success')
166 category='success')
168 Session().commit()
167 Session().commit()
169 except formencode.Invalid as errors:
168 except formencode.Invalid as errors:
170 return htmlfill.render(
169 return htmlfill.render(
171 render('admin/user_groups/user_group_add.mako'),
170 render('admin/user_groups/user_group_add.mako'),
172 defaults=errors.value,
171 defaults=errors.value,
173 errors=errors.error_dict or {},
172 errors=errors.error_dict or {},
174 prefix_error=False,
173 prefix_error=False,
175 encoding="UTF-8",
174 encoding="UTF-8",
176 force_defaults=False)
175 force_defaults=False)
177 except Exception:
176 except Exception:
178 log.exception("Exception creating user group")
177 log.exception("Exception creating user group")
179 h.flash(_('Error occurred during creation of user group %s') \
178 h.flash(_('Error occurred during creation of user group %s') \
180 % request.POST.get('users_group_name'), category='error')
179 % request.POST.get('users_group_name'), category='error')
181
180
182 return redirect(
181 return redirect(
183 url('edit_users_group', user_group_id=user_group.users_group_id))
182 url('edit_users_group', user_group_id=user_group.users_group_id))
184
183
185 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
184 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
186 def new(self):
185 def new(self):
187 """GET /user_groups/new: Form to create a new item"""
186 """GET /user_groups/new: Form to create a new item"""
188 # url('new_users_group')
187 # url('new_users_group')
189 return render('admin/user_groups/user_group_add.mako')
188 return render('admin/user_groups/user_group_add.mako')
190
189
191 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
190 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
192 @auth.CSRFRequired()
191 @auth.CSRFRequired()
193 def update(self, user_group_id):
192 def update(self, user_group_id):
194 """PUT /user_groups/user_group_id: Update an existing item"""
195 # Forms posted to this method should contain a hidden field:
196 # <input type="hidden" name="_method" value="PUT" />
197 # Or using helpers:
198 # h.form(url('users_group', user_group_id=ID),
199 # method='put')
200 # url('users_group', user_group_id=ID)
201
193
202 user_group_id = safe_int(user_group_id)
194 user_group_id = safe_int(user_group_id)
203 c.user_group = UserGroup.get_or_404(user_group_id)
195 c.user_group = UserGroup.get_or_404(user_group_id)
204 c.active = 'settings'
196 c.active = 'settings'
205 self.__load_data(user_group_id)
197 self.__load_data(user_group_id)
206
198
207 users_group_form = UserGroupForm(
199 users_group_form = UserGroupForm(
208 edit=True, old_data=c.user_group.get_dict(), allow_disabled=True)()
200 edit=True, old_data=c.user_group.get_dict(), allow_disabled=True)()
209
201
202 old_values = c.user_group.get_api_data()
210 try:
203 try:
211 form_result = users_group_form.to_python(request.POST)
204 form_result = users_group_form.to_python(request.POST)
212 pstruct = peppercorn.parse(request.POST.items())
205 pstruct = peppercorn.parse(request.POST.items())
213 form_result['users_group_members'] = pstruct['user_group_members']
206 form_result['users_group_members'] = pstruct['user_group_members']
214
207
215 UserGroupModel().update(c.user_group, form_result)
208 UserGroupModel().update(c.user_group, form_result)
216 updated_user_group = form_result['users_group_name']
209 updated_user_group = form_result['users_group_name']
217 action_logger(c.rhodecode_user,
210
218 'admin_updated_users_group:%s' % updated_user_group,
211 audit_logger.store_web(
219 None, self.ip_addr, self.sa)
212 'user_group.edit', action_data={'old_data': old_values},
213 user=c.rhodecode_user)
214
220 h.flash(_('Updated user group %s') % updated_user_group,
215 h.flash(_('Updated user group %s') % updated_user_group,
221 category='success')
216 category='success')
222 Session().commit()
217 Session().commit()
223 except formencode.Invalid as errors:
218 except formencode.Invalid as errors:
224 defaults = errors.value
219 defaults = errors.value
225 e = errors.error_dict or {}
220 e = errors.error_dict or {}
226
221
227 return htmlfill.render(
222 return htmlfill.render(
228 render('admin/user_groups/user_group_edit.mako'),
223 render('admin/user_groups/user_group_edit.mako'),
229 defaults=defaults,
224 defaults=defaults,
230 errors=e,
225 errors=e,
231 prefix_error=False,
226 prefix_error=False,
232 encoding="UTF-8",
227 encoding="UTF-8",
233 force_defaults=False)
228 force_defaults=False)
234 except Exception:
229 except Exception:
235 log.exception("Exception during update of user group")
230 log.exception("Exception during update of user group")
236 h.flash(_('Error occurred during update of user group %s')
231 h.flash(_('Error occurred during update of user group %s')
237 % request.POST.get('users_group_name'), category='error')
232 % request.POST.get('users_group_name'), category='error')
238
233
239 return redirect(url('edit_users_group', user_group_id=user_group_id))
234 return redirect(url('edit_users_group', user_group_id=user_group_id))
240
235
241 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
236 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
242 @auth.CSRFRequired()
237 @auth.CSRFRequired()
243 def delete(self, user_group_id):
238 def delete(self, user_group_id):
244 """DELETE /user_groups/user_group_id: Delete an existing item"""
245 # Forms posted to this method should contain a hidden field:
246 # <input type="hidden" name="_method" value="DELETE" />
247 # Or using helpers:
248 # h.form(url('users_group', user_group_id=ID),
249 # method='delete')
250 # url('users_group', user_group_id=ID)
251 user_group_id = safe_int(user_group_id)
239 user_group_id = safe_int(user_group_id)
252 c.user_group = UserGroup.get_or_404(user_group_id)
240 c.user_group = UserGroup.get_or_404(user_group_id)
253 force = str2bool(request.POST.get('force'))
241 force = str2bool(request.POST.get('force'))
254
242
243 old_values = c.user_group.get_api_data()
255 try:
244 try:
256 UserGroupModel().delete(c.user_group, force=force)
245 UserGroupModel().delete(c.user_group, force=force)
246 audit_logger.store_web(
247 'user.delete', action_data={'old_data': old_values},
248 user=c.rhodecode_user)
257 Session().commit()
249 Session().commit()
258 h.flash(_('Successfully deleted user group'), category='success')
250 h.flash(_('Successfully deleted user group'), category='success')
259 except UserGroupAssignedException as e:
251 except UserGroupAssignedException as e:
260 h.flash(str(e), category='error')
252 h.flash(str(e), category='error')
261 except Exception:
253 except Exception:
262 log.exception("Exception during deletion of user group")
254 log.exception("Exception during deletion of user group")
263 h.flash(_('An error occurred during deletion of user group'),
255 h.flash(_('An error occurred during deletion of user group'),
264 category='error')
256 category='error')
265 return redirect(url('users_groups'))
257 return redirect(url('users_groups'))
266
258
267 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
259 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
268 def edit(self, user_group_id):
260 def edit(self, user_group_id):
269 """GET /user_groups/user_group_id/edit: Form to edit an existing item"""
261 """GET /user_groups/user_group_id/edit: Form to edit an existing item"""
270 # url('edit_users_group', user_group_id=ID)
262 # url('edit_users_group', user_group_id=ID)
271
263
272 user_group_id = safe_int(user_group_id)
264 user_group_id = safe_int(user_group_id)
273 c.user_group = UserGroup.get_or_404(user_group_id)
265 c.user_group = UserGroup.get_or_404(user_group_id)
274 c.active = 'settings'
266 c.active = 'settings'
275 self.__load_data(user_group_id)
267 self.__load_data(user_group_id)
276
268
277 defaults = self.__load_defaults(user_group_id)
269 defaults = self.__load_defaults(user_group_id)
278
270
279 return htmlfill.render(
271 return htmlfill.render(
280 render('admin/user_groups/user_group_edit.mako'),
272 render('admin/user_groups/user_group_edit.mako'),
281 defaults=defaults,
273 defaults=defaults,
282 encoding="UTF-8",
274 encoding="UTF-8",
283 force_defaults=False
275 force_defaults=False
284 )
276 )
285
277
286 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
278 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
287 def edit_perms(self, user_group_id):
279 def edit_perms(self, user_group_id):
288 user_group_id = safe_int(user_group_id)
280 user_group_id = safe_int(user_group_id)
289 c.user_group = UserGroup.get_or_404(user_group_id)
281 c.user_group = UserGroup.get_or_404(user_group_id)
290 c.active = 'perms'
282 c.active = 'perms'
291
283
292 defaults = {}
284 defaults = {}
293 # fill user group users
285 # fill user group users
294 for p in c.user_group.user_user_group_to_perm:
286 for p in c.user_group.user_user_group_to_perm:
295 defaults.update({'u_perm_%s' % p.user.user_id:
287 defaults.update({'u_perm_%s' % p.user.user_id:
296 p.permission.permission_name})
288 p.permission.permission_name})
297
289
298 for p in c.user_group.user_group_user_group_to_perm:
290 for p in c.user_group.user_group_user_group_to_perm:
299 defaults.update({'g_perm_%s' % p.user_group.users_group_id:
291 defaults.update({'g_perm_%s' % p.user_group.users_group_id:
300 p.permission.permission_name})
292 p.permission.permission_name})
301
293
302 return htmlfill.render(
294 return htmlfill.render(
303 render('admin/user_groups/user_group_edit.mako'),
295 render('admin/user_groups/user_group_edit.mako'),
304 defaults=defaults,
296 defaults=defaults,
305 encoding="UTF-8",
297 encoding="UTF-8",
306 force_defaults=False
298 force_defaults=False
307 )
299 )
308
300
309 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
301 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
310 @auth.CSRFRequired()
302 @auth.CSRFRequired()
311 def update_perms(self, user_group_id):
303 def update_perms(self, user_group_id):
312 """
304 """
313 grant permission for given usergroup
305 grant permission for given usergroup
314
306
315 :param user_group_id:
307 :param user_group_id:
316 """
308 """
317 user_group_id = safe_int(user_group_id)
309 user_group_id = safe_int(user_group_id)
318 c.user_group = UserGroup.get_or_404(user_group_id)
310 c.user_group = UserGroup.get_or_404(user_group_id)
319 form = UserGroupPermsForm()().to_python(request.POST)
311 form = UserGroupPermsForm()().to_python(request.POST)
320
312
321 if not c.rhodecode_user.is_admin:
313 if not c.rhodecode_user.is_admin:
322 if self._revoke_perms_on_yourself(form):
314 if self._revoke_perms_on_yourself(form):
323 msg = _('Cannot change permission for yourself as admin')
315 msg = _('Cannot change permission for yourself as admin')
324 h.flash(msg, category='warning')
316 h.flash(msg, category='warning')
325 return redirect(url('edit_user_group_perms', user_group_id=user_group_id))
317 return redirect(url('edit_user_group_perms', user_group_id=user_group_id))
326
318
327 try:
319 try:
328 UserGroupModel().update_permissions(user_group_id,
320 UserGroupModel().update_permissions(user_group_id,
329 form['perm_additions'], form['perm_updates'], form['perm_deletions'])
321 form['perm_additions'], form['perm_updates'], form['perm_deletions'])
330 except RepoGroupAssignmentError:
322 except RepoGroupAssignmentError:
331 h.flash(_('Target group cannot be the same'), category='error')
323 h.flash(_('Target group cannot be the same'), category='error')
332 return redirect(url('edit_user_group_perms', user_group_id=user_group_id))
324 return redirect(url('edit_user_group_perms', user_group_id=user_group_id))
333 #TODO: implement this
325
334 #action_logger(c.rhodecode_user, 'admin_changed_repo_permissions',
326 # TODO(marcink): implement global permissions
335 # repo_name, self.ip_addr, self.sa)
327 # audit_log.store_web('user_group.edit.permissions')
336 Session().commit()
328 Session().commit()
337 h.flash(_('User Group permissions updated'), category='success')
329 h.flash(_('User Group permissions updated'), category='success')
338 return redirect(url('edit_user_group_perms', user_group_id=user_group_id))
330 return redirect(url('edit_user_group_perms', user_group_id=user_group_id))
339
331
340 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
332 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
341 def edit_perms_summary(self, user_group_id):
333 def edit_perms_summary(self, user_group_id):
342 user_group_id = safe_int(user_group_id)
334 user_group_id = safe_int(user_group_id)
343 c.user_group = UserGroup.get_or_404(user_group_id)
335 c.user_group = UserGroup.get_or_404(user_group_id)
344 c.active = 'perms_summary'
336 c.active = 'perms_summary'
345 permissions = {
337 permissions = {
346 'repositories': {},
338 'repositories': {},
347 'repositories_groups': {},
339 'repositories_groups': {},
348 }
340 }
349 ugroup_repo_perms = UserGroupRepoToPerm.query()\
341 ugroup_repo_perms = UserGroupRepoToPerm.query()\
350 .options(joinedload(UserGroupRepoToPerm.permission))\
342 .options(joinedload(UserGroupRepoToPerm.permission))\
351 .options(joinedload(UserGroupRepoToPerm.repository))\
343 .options(joinedload(UserGroupRepoToPerm.repository))\
352 .filter(UserGroupRepoToPerm.users_group_id == user_group_id)\
344 .filter(UserGroupRepoToPerm.users_group_id == user_group_id)\
353 .all()
345 .all()
354
346
355 for gr in ugroup_repo_perms:
347 for gr in ugroup_repo_perms:
356 permissions['repositories'][gr.repository.repo_name] \
348 permissions['repositories'][gr.repository.repo_name] \
357 = gr.permission.permission_name
349 = gr.permission.permission_name
358
350
359 ugroup_group_perms = UserGroupRepoGroupToPerm.query()\
351 ugroup_group_perms = UserGroupRepoGroupToPerm.query()\
360 .options(joinedload(UserGroupRepoGroupToPerm.permission))\
352 .options(joinedload(UserGroupRepoGroupToPerm.permission))\
361 .options(joinedload(UserGroupRepoGroupToPerm.group))\
353 .options(joinedload(UserGroupRepoGroupToPerm.group))\
362 .filter(UserGroupRepoGroupToPerm.users_group_id == user_group_id)\
354 .filter(UserGroupRepoGroupToPerm.users_group_id == user_group_id)\
363 .all()
355 .all()
364
356
365 for gr in ugroup_group_perms:
357 for gr in ugroup_group_perms:
366 permissions['repositories_groups'][gr.group.group_name] \
358 permissions['repositories_groups'][gr.group.group_name] \
367 = gr.permission.permission_name
359 = gr.permission.permission_name
368 c.permissions = permissions
360 c.permissions = permissions
369 return render('admin/user_groups/user_group_edit.mako')
361 return render('admin/user_groups/user_group_edit.mako')
370
362
371 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
363 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
372 def edit_global_perms(self, user_group_id):
364 def edit_global_perms(self, user_group_id):
373 user_group_id = safe_int(user_group_id)
365 user_group_id = safe_int(user_group_id)
374 c.user_group = UserGroup.get_or_404(user_group_id)
366 c.user_group = UserGroup.get_or_404(user_group_id)
375 c.active = 'global_perms'
367 c.active = 'global_perms'
376
368
377 c.default_user = User.get_default_user()
369 c.default_user = User.get_default_user()
378 defaults = c.user_group.get_dict()
370 defaults = c.user_group.get_dict()
379 defaults.update(c.default_user.get_default_perms(suffix='_inherited'))
371 defaults.update(c.default_user.get_default_perms(suffix='_inherited'))
380 defaults.update(c.user_group.get_default_perms())
372 defaults.update(c.user_group.get_default_perms())
381
373
382 return htmlfill.render(
374 return htmlfill.render(
383 render('admin/user_groups/user_group_edit.mako'),
375 render('admin/user_groups/user_group_edit.mako'),
384 defaults=defaults,
376 defaults=defaults,
385 encoding="UTF-8",
377 encoding="UTF-8",
386 force_defaults=False
378 force_defaults=False
387 )
379 )
388
380
389 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
381 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
390 @auth.CSRFRequired()
382 @auth.CSRFRequired()
391 def update_global_perms(self, user_group_id):
383 def update_global_perms(self, user_group_id):
392 """PUT /users_perm/user_group_id: Update an existing item"""
393 # url('users_group_perm', user_group_id=ID, method='put')
394 user_group_id = safe_int(user_group_id)
384 user_group_id = safe_int(user_group_id)
395 user_group = UserGroup.get_or_404(user_group_id)
385 user_group = UserGroup.get_or_404(user_group_id)
396 c.active = 'global_perms'
386 c.active = 'global_perms'
397
387
398 try:
388 try:
399 # first stage that verifies the checkbox
389 # first stage that verifies the checkbox
400 _form = UserIndividualPermissionsForm()
390 _form = UserIndividualPermissionsForm()
401 form_result = _form.to_python(dict(request.POST))
391 form_result = _form.to_python(dict(request.POST))
402 inherit_perms = form_result['inherit_default_permissions']
392 inherit_perms = form_result['inherit_default_permissions']
403 user_group.inherit_default_permissions = inherit_perms
393 user_group.inherit_default_permissions = inherit_perms
404 Session().add(user_group)
394 Session().add(user_group)
405
395
406 if not inherit_perms:
396 if not inherit_perms:
407 # only update the individual ones if we un check the flag
397 # only update the individual ones if we un check the flag
408 _form = UserPermissionsForm(
398 _form = UserPermissionsForm(
409 [x[0] for x in c.repo_create_choices],
399 [x[0] for x in c.repo_create_choices],
410 [x[0] for x in c.repo_create_on_write_choices],
400 [x[0] for x in c.repo_create_on_write_choices],
411 [x[0] for x in c.repo_group_create_choices],
401 [x[0] for x in c.repo_group_create_choices],
412 [x[0] for x in c.user_group_create_choices],
402 [x[0] for x in c.user_group_create_choices],
413 [x[0] for x in c.fork_choices],
403 [x[0] for x in c.fork_choices],
414 [x[0] for x in c.inherit_default_permission_choices])()
404 [x[0] for x in c.inherit_default_permission_choices])()
415
405
416 form_result = _form.to_python(dict(request.POST))
406 form_result = _form.to_python(dict(request.POST))
417 form_result.update({'perm_user_group_id': user_group.users_group_id})
407 form_result.update({'perm_user_group_id': user_group.users_group_id})
418
408
419 PermissionModel().update_user_group_permissions(form_result)
409 PermissionModel().update_user_group_permissions(form_result)
420
410
421 Session().commit()
411 Session().commit()
422 h.flash(_('User Group global permissions updated successfully'),
412 h.flash(_('User Group global permissions updated successfully'),
423 category='success')
413 category='success')
424
414
425 except formencode.Invalid as errors:
415 except formencode.Invalid as errors:
426 defaults = errors.value
416 defaults = errors.value
427 c.user_group = user_group
417 c.user_group = user_group
428 return htmlfill.render(
418 return htmlfill.render(
429 render('admin/user_groups/user_group_edit.mako'),
419 render('admin/user_groups/user_group_edit.mako'),
430 defaults=defaults,
420 defaults=defaults,
431 errors=errors.error_dict or {},
421 errors=errors.error_dict or {},
432 prefix_error=False,
422 prefix_error=False,
433 encoding="UTF-8",
423 encoding="UTF-8",
434 force_defaults=False)
424 force_defaults=False)
435 except Exception:
425 except Exception:
436 log.exception("Exception during permissions saving")
426 log.exception("Exception during permissions saving")
437 h.flash(_('An error occurred during permissions saving'),
427 h.flash(_('An error occurred during permissions saving'),
438 category='error')
428 category='error')
439
429
440 return redirect(url('edit_user_group_global_perms', user_group_id=user_group_id))
430 return redirect(url('edit_user_group_global_perms', user_group_id=user_group_id))
441
431
442 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
432 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
443 def edit_advanced(self, user_group_id):
433 def edit_advanced(self, user_group_id):
444 user_group_id = safe_int(user_group_id)
434 user_group_id = safe_int(user_group_id)
445 c.user_group = UserGroup.get_or_404(user_group_id)
435 c.user_group = UserGroup.get_or_404(user_group_id)
446 c.active = 'advanced'
436 c.active = 'advanced'
447 c.group_members_obj = sorted(
437 c.group_members_obj = sorted(
448 (x.user for x in c.user_group.members),
438 (x.user for x in c.user_group.members),
449 key=lambda u: u.username.lower())
439 key=lambda u: u.username.lower())
450
440
451 c.group_to_repos = sorted(
441 c.group_to_repos = sorted(
452 (x.repository for x in c.user_group.users_group_repo_to_perm),
442 (x.repository for x in c.user_group.users_group_repo_to_perm),
453 key=lambda u: u.repo_name.lower())
443 key=lambda u: u.repo_name.lower())
454
444
455 c.group_to_repo_groups = sorted(
445 c.group_to_repo_groups = sorted(
456 (x.group for x in c.user_group.users_group_repo_group_to_perm),
446 (x.group for x in c.user_group.users_group_repo_group_to_perm),
457 key=lambda u: u.group_name.lower())
447 key=lambda u: u.group_name.lower())
458
448
459 return render('admin/user_groups/user_group_edit.mako')
449 return render('admin/user_groups/user_group_edit.mako')
460
450
461 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
451 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
462 def edit_advanced_set_synchronization(self, user_group_id):
452 def edit_advanced_set_synchronization(self, user_group_id):
463 user_group_id = safe_int(user_group_id)
453 user_group_id = safe_int(user_group_id)
464 user_group = UserGroup.get_or_404(user_group_id)
454 user_group = UserGroup.get_or_404(user_group_id)
465
455
466 existing = user_group.group_data.get('extern_type')
456 existing = user_group.group_data.get('extern_type')
467
457
468 if existing:
458 if existing:
469 new_state = user_group.group_data
459 new_state = user_group.group_data
470 new_state['extern_type'] = None
460 new_state['extern_type'] = None
471 else:
461 else:
472 new_state = user_group.group_data
462 new_state = user_group.group_data
473 new_state['extern_type'] = 'manual'
463 new_state['extern_type'] = 'manual'
474 new_state['extern_type_set_by'] = c.rhodecode_user.username
464 new_state['extern_type_set_by'] = c.rhodecode_user.username
475
465
476 try:
466 try:
477 user_group.group_data = new_state
467 user_group.group_data = new_state
478 Session().add(user_group)
468 Session().add(user_group)
479 Session().commit()
469 Session().commit()
480
470
481 h.flash(_('User Group synchronization updated successfully'),
471 h.flash(_('User Group synchronization updated successfully'),
482 category='success')
472 category='success')
483 except Exception:
473 except Exception:
484 log.exception("Exception during sync settings saving")
474 log.exception("Exception during sync settings saving")
485 h.flash(_('An error occurred during synchronization update'),
475 h.flash(_('An error occurred during synchronization update'),
486 category='error')
476 category='error')
487
477
488 return redirect(
478 return redirect(
489 url('edit_user_group_advanced', user_group_id=user_group_id))
479 url('edit_user_group_advanced', user_group_id=user_group_id))
490
480
491 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
481 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
492 @XHRRequired()
482 @XHRRequired()
493 @jsonify
483 @jsonify
494 def user_group_members(self, user_group_id):
484 def user_group_members(self, user_group_id):
485 """
486 Return members of given user group
487 """
495 user_group_id = safe_int(user_group_id)
488 user_group_id = safe_int(user_group_id)
496 user_group = UserGroup.get_or_404(user_group_id)
489 user_group = UserGroup.get_or_404(user_group_id)
497 group_members_obj = sorted((x.user for x in user_group.members),
490 group_members_obj = sorted((x.user for x in user_group.members),
498 key=lambda u: u.username.lower())
491 key=lambda u: u.username.lower())
499
492
500 group_members = [
493 group_members = [
501 {
494 {
502 'id': user.user_id,
495 'id': user.user_id,
503 'first_name': user.name,
496 'first_name': user.name,
504 'last_name': user.lastname,
497 'last_name': user.lastname,
505 'username': user.username,
498 'username': user.username,
506 'icon_link': h.gravatar_url(user.email, 30),
499 'icon_link': h.gravatar_url(user.email, 30),
507 'value_display': h.person(user.email),
500 'value_display': h.person(user.email),
508 'value': user.username,
501 'value': user.username,
509 'value_type': 'user',
502 'value_type': 'user',
510 'active': user.active,
503 'active': user.active,
511 }
504 }
512 for user in group_members_obj
505 for user in group_members_obj
513 ]
506 ]
514
507
515 return {
508 return {
516 'members': group_members
509 'members': group_members
517 }
510 }
@@ -1,233 +1,240 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2017-2017 RhodeCode GmbH
3 # Copyright (C) 2017-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import logging
21 import logging
22 import datetime
22 import datetime
23
23
24 from rhodecode.model import meta
24 from rhodecode.model import meta
25 from rhodecode.model.db import User, UserLog, Repository
25 from rhodecode.model.db import User, UserLog, Repository
26
26
27
27
28 log = logging.getLogger(__name__)
28 log = logging.getLogger(__name__)
29
29
30 # action as key, and expected action_data as value
30 # action as key, and expected action_data as value
31 ACTIONS = {
31 ACTIONS = {
32 'user.login.success': {'user_agent': ''},
32 'user.login.success': {'user_agent': ''},
33 'user.login.failure': {'user_agent': ''},
33 'user.login.failure': {'user_agent': ''},
34 'user.logout': {'user_agent': ''},
34 'user.logout': {'user_agent': ''},
35 'user.password.reset_request': {},
35 'user.password.reset_request': {},
36 'user.push': {'user_agent': '', 'commit_ids': []},
36 'user.push': {'user_agent': '', 'commit_ids': []},
37 'user.pull': {'user_agent': ''},
37 'user.pull': {'user_agent': ''},
38
38
39 'user.create': {'data': {}},
39 'user.create': {'data': {}},
40 'user.delete': {'old_data': {}},
40 'user.delete': {'old_data': {}},
41 'user.edit': {'old_data': {}},
41 'user.edit': {'old_data': {}},
42 'user.edit.permissions': {},
42 'user.edit.permissions': {},
43 'user.edit.ip.add': {},
43 'user.edit.ip.add': {},
44 'user.edit.ip.delete': {},
44 'user.edit.ip.delete': {},
45 'user.edit.token.add': {},
45 'user.edit.token.add': {},
46 'user.edit.token.delete': {},
46 'user.edit.token.delete': {},
47 'user.edit.email.add': {},
47 'user.edit.email.add': {},
48 'user.edit.email.delete': {},
48 'user.edit.email.delete': {},
49 'user.edit.password_reset.enabled': {},
49 'user.edit.password_reset.enabled': {},
50 'user.edit.password_reset.disabled': {},
50 'user.edit.password_reset.disabled': {},
51
51
52 'user_group.create': {'data': {}},
53 'user_group.delete': {'old_data': {}},
54 'user_group.edit': {'old_data': {}},
55 'user_group.edit.permissions': {},
56 'user_group.edit.member.add': {},
57 'user_group.edit.member.delete': {},
58
52 'repo.create': {'data': {}},
59 'repo.create': {'data': {}},
53 'repo.fork': {'data': {}},
60 'repo.fork': {'data': {}},
54 'repo.edit': {'old_data': {}},
61 'repo.edit': {'old_data': {}},
55 'repo.edit.permissions': {},
62 'repo.edit.permissions': {},
56 'repo.delete': {'old_data': {}},
63 'repo.delete': {'old_data': {}},
57 'repo.commit.strip': {},
64 'repo.commit.strip': {},
58 'repo.archive.download': {},
65 'repo.archive.download': {},
59
66
60 'repo_group.create': {'data': {}},
67 'repo_group.create': {'data': {}},
61 'repo_group.edit': {'old_data': {}},
68 'repo_group.edit': {'old_data': {}},
62 'repo_group.edit.permissions': {},
69 'repo_group.edit.permissions': {},
63 'repo_group.delete': {'old_data': {}},
70 'repo_group.delete': {'old_data': {}},
64 }
71 }
65
72
66 SOURCE_WEB = 'source_web'
73 SOURCE_WEB = 'source_web'
67 SOURCE_API = 'source_api'
74 SOURCE_API = 'source_api'
68
75
69
76
70 class UserWrap(object):
77 class UserWrap(object):
71 """
78 """
72 Fake object used to imitate AuthUser
79 Fake object used to imitate AuthUser
73 """
80 """
74
81
75 def __init__(self, user_id=None, username=None, ip_addr=None):
82 def __init__(self, user_id=None, username=None, ip_addr=None):
76 self.user_id = user_id
83 self.user_id = user_id
77 self.username = username
84 self.username = username
78 self.ip_addr = ip_addr
85 self.ip_addr = ip_addr
79
86
80
87
81 class RepoWrap(object):
88 class RepoWrap(object):
82 """
89 """
83 Fake object used to imitate RepoObject that audit logger requires
90 Fake object used to imitate RepoObject that audit logger requires
84 """
91 """
85
92
86 def __init__(self, repo_id=None, repo_name=None):
93 def __init__(self, repo_id=None, repo_name=None):
87 self.repo_id = repo_id
94 self.repo_id = repo_id
88 self.repo_name = repo_name
95 self.repo_name = repo_name
89
96
90
97
91 def _store_log(action_name, action_data, user_id, username, user_data,
98 def _store_log(action_name, action_data, user_id, username, user_data,
92 ip_address, repository_id, repository_name):
99 ip_address, repository_id, repository_name):
93 user_log = UserLog()
100 user_log = UserLog()
94 user_log.version = UserLog.VERSION_2
101 user_log.version = UserLog.VERSION_2
95
102
96 user_log.action = action_name
103 user_log.action = action_name
97 user_log.action_data = action_data
104 user_log.action_data = action_data
98
105
99 user_log.user_ip = ip_address
106 user_log.user_ip = ip_address
100
107
101 user_log.user_id = user_id
108 user_log.user_id = user_id
102 user_log.username = username
109 user_log.username = username
103 user_log.user_data = user_data
110 user_log.user_data = user_data
104
111
105 user_log.repository_id = repository_id
112 user_log.repository_id = repository_id
106 user_log.repository_name = repository_name
113 user_log.repository_name = repository_name
107
114
108 user_log.action_date = datetime.datetime.now()
115 user_log.action_date = datetime.datetime.now()
109
116
110 log.info('AUDIT: Logging action: `%s` by user:id:%s[%s] ip:%s',
117 log.info('AUDIT: Logging action: `%s` by user:id:%s[%s] ip:%s',
111 action_name, user_id, username, ip_address)
118 action_name, user_id, username, ip_address)
112
119
113 return user_log
120 return user_log
114
121
115
122
116 def store_web(*args, **kwargs):
123 def store_web(*args, **kwargs):
117 if 'action_data' not in kwargs:
124 if 'action_data' not in kwargs:
118 kwargs['action_data'] = {}
125 kwargs['action_data'] = {}
119 kwargs['action_data'].update({
126 kwargs['action_data'].update({
120 'source': SOURCE_WEB
127 'source': SOURCE_WEB
121 })
128 })
122 return store(*args, **kwargs)
129 return store(*args, **kwargs)
123
130
124
131
125 def store_api(*args, **kwargs):
132 def store_api(*args, **kwargs):
126 if 'action_data' not in kwargs:
133 if 'action_data' not in kwargs:
127 kwargs['action_data'] = {}
134 kwargs['action_data'] = {}
128 kwargs['action_data'].update({
135 kwargs['action_data'].update({
129 'source': SOURCE_API
136 'source': SOURCE_API
130 })
137 })
131 return store(*args, **kwargs)
138 return store(*args, **kwargs)
132
139
133
140
134 def store(action, user, action_data=None, user_data=None, ip_addr=None,
141 def store(action, user, action_data=None, user_data=None, ip_addr=None,
135 repo=None, sa_session=None, commit=False):
142 repo=None, sa_session=None, commit=False):
136 """
143 """
137 Audit logger for various actions made by users, typically this
144 Audit logger for various actions made by users, typically this
138 results in a call such::
145 results in a call such::
139
146
140 from rhodecode.lib import audit_logger
147 from rhodecode.lib import audit_logger
141
148
142 audit_logger.store(
149 audit_logger.store(
143 action='repo.edit', user=self._rhodecode_user)
150 action='repo.edit', user=self._rhodecode_user)
144 audit_logger.store(
151 audit_logger.store(
145 action='repo.delete', action_data={'repo_data': repo_data},
152 action='repo.delete', action_data={'repo_data': repo_data},
146 user=audit_logger.UserWrap(username='itried-login', ip_addr='8.8.8.8'))
153 user=audit_logger.UserWrap(username='itried-login', ip_addr='8.8.8.8'))
147
154
148 # repo action
155 # repo action
149 audit_logger.store(
156 audit_logger.store(
150 action='repo.delete',
157 action='repo.delete',
151 user=audit_logger.UserWrap(username='itried-login', ip_addr='8.8.8.8'),
158 user=audit_logger.UserWrap(username='itried-login', ip_addr='8.8.8.8'),
152 repo=audit_logger.RepoWrap(repo_name='some-repo'))
159 repo=audit_logger.RepoWrap(repo_name='some-repo'))
153
160
154 # repo action, when we know and have the repository object already
161 # repo action, when we know and have the repository object already
155 audit_logger.store(
162 audit_logger.store(
156 action='repo.delete',
163 action='repo.delete',
157 action_data={'source': audit_logger.SOURCE_WEB, },
164 action_data={'source': audit_logger.SOURCE_WEB, },
158 user=self._rhodecode_user,
165 user=self._rhodecode_user,
159 repo=repo_object)
166 repo=repo_object)
160
167
161 # alternative wrapper to the above
168 # alternative wrapper to the above
162 audit_logger.store_web(
169 audit_logger.store_web(
163 action='repo.delete',
170 action='repo.delete',
164 action_data={},
171 action_data={},
165 user=self._rhodecode_user,
172 user=self._rhodecode_user,
166 repo=repo_object)
173 repo=repo_object)
167
174
168 # without an user ?
175 # without an user ?
169 audit_logger.store(
176 audit_logger.store(
170 action='user.login.failure',
177 action='user.login.failure',
171 user=audit_logger.UserWrap(
178 user=audit_logger.UserWrap(
172 username=self.request.params.get('username'),
179 username=self.request.params.get('username'),
173 ip_addr=self.request.remote_addr))
180 ip_addr=self.request.remote_addr))
174
181
175 """
182 """
176 from rhodecode.lib.utils2 import safe_unicode
183 from rhodecode.lib.utils2 import safe_unicode
177 from rhodecode.lib.auth import AuthUser
184 from rhodecode.lib.auth import AuthUser
178
185
179 action_spec = ACTIONS.get(action, None)
186 action_spec = ACTIONS.get(action, None)
180 if action_spec is None:
187 if action_spec is None:
181 raise ValueError('Action `{}` is not supported'.format(action))
188 raise ValueError('Action `{}` is not supported'.format(action))
182
189
183 if not sa_session:
190 if not sa_session:
184 sa_session = meta.Session()
191 sa_session = meta.Session()
185
192
186 try:
193 try:
187 username = getattr(user, 'username', None)
194 username = getattr(user, 'username', None)
188 if not username:
195 if not username:
189 pass
196 pass
190
197
191 user_id = getattr(user, 'user_id', None)
198 user_id = getattr(user, 'user_id', None)
192 if not user_id:
199 if not user_id:
193 # maybe we have username ? Try to figure user_id from username
200 # maybe we have username ? Try to figure user_id from username
194 if username:
201 if username:
195 user_id = getattr(
202 user_id = getattr(
196 User.get_by_username(username), 'user_id', None)
203 User.get_by_username(username), 'user_id', None)
197
204
198 ip_addr = ip_addr or getattr(user, 'ip_addr', None)
205 ip_addr = ip_addr or getattr(user, 'ip_addr', None)
199 if not ip_addr:
206 if not ip_addr:
200 pass
207 pass
201
208
202 if not user_data:
209 if not user_data:
203 # try to get this from the auth user
210 # try to get this from the auth user
204 if isinstance(user, AuthUser):
211 if isinstance(user, AuthUser):
205 user_data = {
212 user_data = {
206 'username': user.username,
213 'username': user.username,
207 'email': user.email,
214 'email': user.email,
208 }
215 }
209
216
210 repository_name = getattr(repo, 'repo_name', None)
217 repository_name = getattr(repo, 'repo_name', None)
211 repository_id = getattr(repo, 'repo_id', None)
218 repository_id = getattr(repo, 'repo_id', None)
212 if not repository_id:
219 if not repository_id:
213 # maybe we have repo_name ? Try to figure repo_id from repo_name
220 # maybe we have repo_name ? Try to figure repo_id from repo_name
214 if repository_name:
221 if repository_name:
215 repository_id = getattr(
222 repository_id = getattr(
216 Repository.get_by_repo_name(repository_name), 'repo_id', None)
223 Repository.get_by_repo_name(repository_name), 'repo_id', None)
217
224
218 user_log = _store_log(
225 user_log = _store_log(
219 action_name=safe_unicode(action),
226 action_name=safe_unicode(action),
220 action_data=action_data or {},
227 action_data=action_data or {},
221 user_id=user_id,
228 user_id=user_id,
222 username=username,
229 username=username,
223 user_data=user_data or {},
230 user_data=user_data or {},
224 ip_address=safe_unicode(ip_addr),
231 ip_address=safe_unicode(ip_addr),
225 repository_id=repository_id,
232 repository_id=repository_id,
226 repository_name=repository_name
233 repository_name=repository_name
227 )
234 )
228 sa_session.add(user_log)
235 sa_session.add(user_log)
229 if commit:
236 if commit:
230 sa_session.commit()
237 sa_session.commit()
231
238
232 except Exception:
239 except Exception:
233 log.exception('AUDIT: failed to store audit log')
240 log.exception('AUDIT: failed to store audit log')
General Comments 0
You need to be logged in to leave comments. Login now