##// END OF EJS Templates
fix resubmition issues when there are errors in user edit form
marcink -
r2545:385b768b beta
parent child Browse files
Show More
@@ -1,252 +1,252 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.admin.users
3 rhodecode.controllers.admin.users
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Users crud controller for pylons
6 Users crud controller for pylons
7
7
8 :created_on: Apr 4, 2010
8 :created_on: Apr 4, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import logging
26 import logging
27 import traceback
27 import traceback
28 import formencode
28 import formencode
29
29
30 from formencode import htmlfill
30 from formencode import htmlfill
31 from pylons import request, session, tmpl_context as c, url, config
31 from pylons import request, session, tmpl_context as c, url, config
32 from pylons.controllers.util import redirect
32 from pylons.controllers.util import redirect
33 from pylons.i18n.translation import _
33 from pylons.i18n.translation import _
34
34
35 from rhodecode.lib.exceptions import DefaultUserException, \
35 from rhodecode.lib.exceptions import DefaultUserException, \
36 UserOwnsReposException
36 UserOwnsReposException
37 from rhodecode.lib import helpers as h
37 from rhodecode.lib import helpers as h
38 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator,\
38 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator,\
39 AuthUser
39 AuthUser
40 from rhodecode.lib.base import BaseController, render
40 from rhodecode.lib.base import BaseController, render
41
41
42 from rhodecode.model.db import User, Permission, UserEmailMap
42 from rhodecode.model.db import User, Permission, UserEmailMap
43 from rhodecode.model.forms import UserForm
43 from rhodecode.model.forms import UserForm
44 from rhodecode.model.user import UserModel
44 from rhodecode.model.user import UserModel
45 from rhodecode.model.meta import Session
45 from rhodecode.model.meta import Session
46 from rhodecode.lib.utils import action_logger
46 from rhodecode.lib.utils import action_logger
47
47
48 log = logging.getLogger(__name__)
48 log = logging.getLogger(__name__)
49
49
50
50
51 class UsersController(BaseController):
51 class UsersController(BaseController):
52 """REST Controller styled on the Atom Publishing Protocol"""
52 """REST Controller styled on the Atom Publishing Protocol"""
53 # To properly map this controller, ensure your config/routing.py
53 # To properly map this controller, ensure your config/routing.py
54 # file has a resource setup:
54 # file has a resource setup:
55 # map.resource('user', 'users')
55 # map.resource('user', 'users')
56
56
57 @LoginRequired()
57 @LoginRequired()
58 @HasPermissionAllDecorator('hg.admin')
58 @HasPermissionAllDecorator('hg.admin')
59 def __before__(self):
59 def __before__(self):
60 c.admin_user = session.get('admin_user')
60 c.admin_user = session.get('admin_user')
61 c.admin_username = session.get('admin_username')
61 c.admin_username = session.get('admin_username')
62 super(UsersController, self).__before__()
62 super(UsersController, self).__before__()
63 c.available_permissions = config['available_permissions']
63 c.available_permissions = config['available_permissions']
64
64
65 def index(self, format='html'):
65 def index(self, format='html'):
66 """GET /users: All items in the collection"""
66 """GET /users: All items in the collection"""
67 # url('users')
67 # url('users')
68
68
69 c.users_list = self.sa.query(User).all()
69 c.users_list = self.sa.query(User).all()
70 return render('admin/users/users.html')
70 return render('admin/users/users.html')
71
71
72 def create(self):
72 def create(self):
73 """POST /users: Create a new item"""
73 """POST /users: Create a new item"""
74 # url('users')
74 # url('users')
75
75
76 user_model = UserModel()
76 user_model = UserModel()
77 user_form = UserForm()()
77 user_form = UserForm()()
78 try:
78 try:
79 form_result = user_form.to_python(dict(request.POST))
79 form_result = user_form.to_python(dict(request.POST))
80 user_model.create(form_result)
80 user_model.create(form_result)
81 usr = form_result['username']
81 usr = form_result['username']
82 action_logger(self.rhodecode_user, 'admin_created_user:%s' % usr,
82 action_logger(self.rhodecode_user, 'admin_created_user:%s' % usr,
83 None, self.ip_addr, self.sa)
83 None, self.ip_addr, self.sa)
84 h.flash(_('created user %s') % usr,
84 h.flash(_('created user %s') % usr,
85 category='success')
85 category='success')
86 Session.commit()
86 Session.commit()
87 except formencode.Invalid, errors:
87 except formencode.Invalid, errors:
88 return htmlfill.render(
88 return htmlfill.render(
89 render('admin/users/user_add.html'),
89 render('admin/users/user_add.html'),
90 defaults=errors.value,
90 defaults=errors.value,
91 errors=errors.error_dict or {},
91 errors=errors.error_dict or {},
92 prefix_error=False,
92 prefix_error=False,
93 encoding="UTF-8")
93 encoding="UTF-8")
94 except Exception:
94 except Exception:
95 log.error(traceback.format_exc())
95 log.error(traceback.format_exc())
96 h.flash(_('error occurred during creation of user %s') \
96 h.flash(_('error occurred during creation of user %s') \
97 % request.POST.get('username'), category='error')
97 % request.POST.get('username'), category='error')
98 return redirect(url('users'))
98 return redirect(url('users'))
99
99
100 def new(self, format='html'):
100 def new(self, format='html'):
101 """GET /users/new: Form to create a new item"""
101 """GET /users/new: Form to create a new item"""
102 # url('new_user')
102 # url('new_user')
103 return render('admin/users/user_add.html')
103 return render('admin/users/user_add.html')
104
104
105 def update(self, id):
105 def update(self, id):
106 """PUT /users/id: Update an existing item"""
106 """PUT /users/id: Update an existing item"""
107 # Forms posted to this method should contain a hidden field:
107 # Forms posted to this method should contain a hidden field:
108 # <input type="hidden" name="_method" value="PUT" />
108 # <input type="hidden" name="_method" value="PUT" />
109 # Or using helpers:
109 # Or using helpers:
110 # h.form(url('update_user', id=ID),
110 # h.form(url('update_user', id=ID),
111 # method='put')
111 # method='put')
112 # url('user', id=ID)
112 # url('user', id=ID)
113 user_model = UserModel()
113 user_model = UserModel()
114 c.user = user_model.get(id)
114 c.user = user_model.get(id)
115 c.perm_user = AuthUser(user_id=id)
115 c.perm_user = AuthUser(user_id=id)
116 _form = UserForm(edit=True, old_data={'user_id': id,
116 _form = UserForm(edit=True, old_data={'user_id': id,
117 'email': c.user.email})()
117 'email': c.user.email})()
118 form_result = {}
118 form_result = {}
119 try:
119 try:
120 form_result = _form.to_python(dict(request.POST))
120 form_result = _form.to_python(dict(request.POST))
121 user_model.update(id, form_result)
121 user_model.update(id, form_result)
122 usr = form_result['username']
122 usr = form_result['username']
123 action_logger(self.rhodecode_user, 'admin_updated_user:%s' % usr,
123 action_logger(self.rhodecode_user, 'admin_updated_user:%s' % usr,
124 None, self.ip_addr, self.sa)
124 None, self.ip_addr, self.sa)
125 h.flash(_('User updated successfully'), category='success')
125 h.flash(_('User updated successfully'), category='success')
126 Session.commit()
126 Session.commit()
127 except formencode.Invalid, errors:
127 except formencode.Invalid, errors:
128 c.user_email_map = UserEmailMap.query()\
128 c.user_email_map = UserEmailMap.query()\
129 .filter(UserEmailMap.user == c.user).all()
129 .filter(UserEmailMap.user == c.user).all()
130 defaults = errors.value
130 defaults = errors.value
131 e = errors.error_dict or {}
131 e = errors.error_dict or {}
132 perm = Permission.get_by_key('hg.create.repository')
132 perm = Permission.get_by_key('hg.create.repository')
133 defaults.update({'create_repo_perm': user_model.has_perm(id, perm)})
133 defaults.update({'create_repo_perm': user_model.has_perm(id, perm)})
134 defaults.update({'_method': 'put'})
134 return htmlfill.render(
135 return htmlfill.render(
135 render('admin/users/user_edit.html'),
136 render('admin/users/user_edit.html'),
136 defaults=defaults,
137 defaults=defaults,
137 errors=e,
138 errors=e,
138 prefix_error=False,
139 prefix_error=False,
139 encoding="UTF-8")
140 encoding="UTF-8")
140 except Exception:
141 except Exception:
141 log.error(traceback.format_exc())
142 log.error(traceback.format_exc())
142 h.flash(_('error occurred during update of user %s') \
143 h.flash(_('error occurred during update of user %s') \
143 % form_result.get('username'), category='error')
144 % form_result.get('username'), category='error')
144
145 return redirect(url('users'))
145 return redirect(url('users'))
146
146
147 def delete(self, id):
147 def delete(self, id):
148 """DELETE /users/id: Delete an existing item"""
148 """DELETE /users/id: Delete an existing item"""
149 # Forms posted to this method should contain a hidden field:
149 # Forms posted to this method should contain a hidden field:
150 # <input type="hidden" name="_method" value="DELETE" />
150 # <input type="hidden" name="_method" value="DELETE" />
151 # Or using helpers:
151 # Or using helpers:
152 # h.form(url('delete_user', id=ID),
152 # h.form(url('delete_user', id=ID),
153 # method='delete')
153 # method='delete')
154 # url('user', id=ID)
154 # url('user', id=ID)
155 user_model = UserModel()
155 user_model = UserModel()
156 try:
156 try:
157 user_model.delete(id)
157 user_model.delete(id)
158 Session.commit()
158 Session.commit()
159 h.flash(_('successfully deleted user'), category='success')
159 h.flash(_('successfully deleted user'), category='success')
160 except (UserOwnsReposException, DefaultUserException), e:
160 except (UserOwnsReposException, DefaultUserException), e:
161 h.flash(e, category='warning')
161 h.flash(e, category='warning')
162 except Exception:
162 except Exception:
163 log.error(traceback.format_exc())
163 log.error(traceback.format_exc())
164 h.flash(_('An error occurred during deletion of user'),
164 h.flash(_('An error occurred during deletion of user'),
165 category='error')
165 category='error')
166 return redirect(url('users'))
166 return redirect(url('users'))
167
167
168 def show(self, id, format='html'):
168 def show(self, id, format='html'):
169 """GET /users/id: Show a specific item"""
169 """GET /users/id: Show a specific item"""
170 # url('user', id=ID)
170 # url('user', id=ID)
171
171
172 def edit(self, id, format='html'):
172 def edit(self, id, format='html'):
173 """GET /users/id/edit: Form to edit an existing item"""
173 """GET /users/id/edit: Form to edit an existing item"""
174 # url('edit_user', id=ID)
174 # url('edit_user', id=ID)
175 c.user = User.get_or_404(id)
175 c.user = User.get_or_404(id)
176
176
177 if c.user.username == 'default':
177 if c.user.username == 'default':
178 h.flash(_("You can't edit this user"), category='warning')
178 h.flash(_("You can't edit this user"), category='warning')
179 return redirect(url('users'))
179 return redirect(url('users'))
180 c.perm_user = AuthUser(user_id=id)
180 c.perm_user = AuthUser(user_id=id)
181 c.user.permissions = {}
181 c.user.permissions = {}
182 c.granted_permissions = UserModel().fill_perms(c.user)\
182 c.granted_permissions = UserModel().fill_perms(c.user)\
183 .permissions['global']
183 .permissions['global']
184 c.user_email_map = UserEmailMap.query()\
184 c.user_email_map = UserEmailMap.query()\
185 .filter(UserEmailMap.user == c.user).all()
185 .filter(UserEmailMap.user == c.user).all()
186 defaults = c.user.get_dict()
186 defaults = c.user.get_dict()
187 perm = Permission.get_by_key('hg.create.repository')
187 perm = Permission.get_by_key('hg.create.repository')
188 defaults.update({'create_repo_perm': UserModel().has_perm(id, perm)})
188 defaults.update({'create_repo_perm': UserModel().has_perm(id, perm)})
189
189
190 return htmlfill.render(
190 return htmlfill.render(
191 render('admin/users/user_edit.html'),
191 render('admin/users/user_edit.html'),
192 defaults=defaults,
192 defaults=defaults,
193 encoding="UTF-8",
193 encoding="UTF-8",
194 force_defaults=False
194 force_defaults=False
195 )
195 )
196
196
197 def update_perm(self, id):
197 def update_perm(self, id):
198 """PUT /users_perm/id: Update an existing item"""
198 """PUT /users_perm/id: Update an existing item"""
199 # url('user_perm', id=ID, method='put')
199 # url('user_perm', id=ID, method='put')
200
200
201 grant_perm = request.POST.get('create_repo_perm', False)
201 grant_perm = request.POST.get('create_repo_perm', False)
202 user_model = UserModel()
202 user_model = UserModel()
203
203
204 if grant_perm:
204 if grant_perm:
205 perm = Permission.get_by_key('hg.create.none')
205 perm = Permission.get_by_key('hg.create.none')
206 user_model.revoke_perm(id, perm)
206 user_model.revoke_perm(id, perm)
207
207
208 perm = Permission.get_by_key('hg.create.repository')
208 perm = Permission.get_by_key('hg.create.repository')
209 user_model.grant_perm(id, perm)
209 user_model.grant_perm(id, perm)
210 h.flash(_("Granted 'repository create' permission to user"),
210 h.flash(_("Granted 'repository create' permission to user"),
211 category='success')
211 category='success')
212 Session.commit()
212 Session.commit()
213 else:
213 else:
214 perm = Permission.get_by_key('hg.create.repository')
214 perm = Permission.get_by_key('hg.create.repository')
215 user_model.revoke_perm(id, perm)
215 user_model.revoke_perm(id, perm)
216
216
217 perm = Permission.get_by_key('hg.create.none')
217 perm = Permission.get_by_key('hg.create.none')
218 user_model.grant_perm(id, perm)
218 user_model.grant_perm(id, perm)
219 h.flash(_("Revoked 'repository create' permission to user"),
219 h.flash(_("Revoked 'repository create' permission to user"),
220 category='success')
220 category='success')
221 Session.commit()
221 Session.commit()
222 return redirect(url('edit_user', id=id))
222 return redirect(url('edit_user', id=id))
223
223
224 def add_email(self, id):
224 def add_email(self, id):
225 """POST /user_emails:Add an existing item"""
225 """POST /user_emails:Add an existing item"""
226 # url('user_emails', id=ID, method='put')
226 # url('user_emails', id=ID, method='put')
227
227
228 #TODO: validation and form !!!
228 #TODO: validation and form !!!
229 email = request.POST.get('new_email')
229 email = request.POST.get('new_email')
230 user_model = UserModel()
230 user_model = UserModel()
231
231
232 try:
232 try:
233 user_model.add_extra_email(id, email)
233 user_model.add_extra_email(id, email)
234 Session.commit()
234 Session.commit()
235 h.flash(_("Added email %s to user" % email), category='success')
235 h.flash(_("Added email %s to user" % email), category='success')
236 except formencode.Invalid, error:
236 except formencode.Invalid, error:
237 msg = error.error_dict['email']
237 msg = error.error_dict['email']
238 h.flash(msg, category='error')
238 h.flash(msg, category='error')
239 except Exception:
239 except Exception:
240 log.error(traceback.format_exc())
240 log.error(traceback.format_exc())
241 h.flash(_('An error occurred during email saving'),
241 h.flash(_('An error occurred during email saving'),
242 category='error')
242 category='error')
243 return redirect(url('edit_user', id=id))
243 return redirect(url('edit_user', id=id))
244
244
245 def delete_email(self, id):
245 def delete_email(self, id):
246 """DELETE /user_emails_delete/id: Delete an existing item"""
246 """DELETE /user_emails_delete/id: Delete an existing item"""
247 # url('user_emails_delete', id=ID, method='delete')
247 # url('user_emails_delete', id=ID, method='delete')
248 user_model = UserModel()
248 user_model = UserModel()
249 user_model.delete_extra_email(id, request.POST.get('del_email'))
249 user_model.delete_extra_email(id, request.POST.get('del_email'))
250 Session.commit()
250 Session.commit()
251 h.flash(_("Removed email from user"), category='success')
251 h.flash(_("Removed email from user"), category='success')
252 return redirect(url('edit_user', id=id))
252 return redirect(url('edit_user', id=id))
General Comments 0
You need to be logged in to leave comments. Login now