##// END OF EJS Templates
fixed bug for user update, when password was always set.
marcink -
r347:40bccabf default
parent child Browse files
Show More
@@ -1,270 +1,271
1 1 """ this is forms validation classes
2 2 http://formencode.org/module-formencode.validators.html
3 3 for list off all availible validators
4 4
5 5 we can create our own validators
6 6
7 7 The table below outlines the options which can be used in a schema in addition to the validators themselves
8 8 pre_validators [] These validators will be applied before the schema
9 9 chained_validators [] These validators will be applied after the schema
10 10 allow_extra_fields False If True, then it is not an error when keys that aren't associated with a validator are present
11 11 filter_extra_fields False If True, then keys that aren't associated with a validator are removed
12 12 if_key_missing NoDefault If this is given, then any keys that aren't available but are expected will be replaced with this value (and then validated). This does not override a present .if_missing attribute on validators. NoDefault is a special FormEncode class to mean that no default values has been specified and therefore missing keys shouldn't take a default value.
13 13 ignore_key_missing False If True, then missing keys will be missing in the result, if the validator doesn't have .if_missing on it already
14 14
15 15
16 16 <name> = formencode.validators.<name of validator>
17 17 <name> must equal form name
18 18 list=[1,2,3,4,5]
19 19 for SELECT use formencode.All(OneOf(list), Int())
20 20
21 21 """
22 22 from formencode import All
23 23 from formencode.validators import UnicodeString, OneOf, Int, Number, Regex, \
24 24 Email, Bool, StringBoolean
25 25 from pylons import session
26 26 from pylons.i18n.translation import _
27 27 from pylons_app.lib.auth import get_crypt_password
28 28 import pylons_app.lib.helpers as h
29 29 from pylons_app.model import meta
30 30 from pylons_app.model.db import User, Repository
31 31 from sqlalchemy.exc import OperationalError
32 32 from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
33 33 from webhelpers.pylonslib.secure_form import authentication_token
34 34 import datetime
35 35 import formencode
36 36 import logging
37 37 log = logging.getLogger(__name__)
38 38
39 39
40 40 #this is needed to translate the messages using _() in validators
41 41 class State_obj(object):
42 42 _ = staticmethod(_)
43 43
44 44 #===============================================================================
45 45 # VALIDATORS
46 46 #===============================================================================
47 47 class ValidAuthToken(formencode.validators.FancyValidator):
48 48 messages = {'invalid_token':_('Token mismatch')}
49 49
50 50 def validate_python(self, value, state):
51 51
52 52 if value != authentication_token():
53 53 raise formencode.Invalid(self.message('invalid_token', state,
54 54 search_number=value), value, state)
55 55 class ValidUsername(formencode.validators.FancyValidator):
56 56
57 57 def validate_python(self, value, state):
58 58 if value in ['default', 'new_user']:
59 59 raise formencode.Invalid(_('Invalid username'), value, state)
60 60
61 61 class ValidPassword(formencode.validators.FancyValidator):
62 62
63 63 def to_python(self, value, state):
64 if value:
64 65 return get_crypt_password(value)
65 66
66 67 class ValidAuth(formencode.validators.FancyValidator):
67 68 messages = {
68 69 'invalid_password':_('invalid password'),
69 70 'invalid_login':_('invalid user name'),
70 71 'disabled_account':_('Your acccount is disabled')
71 72
72 73 }
73 74 #error mapping
74 75 e_dict = {'username':messages['invalid_login'],
75 76 'password':messages['invalid_password']}
76 77 e_dict_disable = {'username':messages['disabled_account']}
77 78
78 79 def validate_python(self, value, state):
79 80 sa = meta.Session
80 81 crypted_passwd = get_crypt_password(value['password'])
81 82 username = value['username']
82 83 try:
83 84 user = sa.query(User).filter(User.username == username).one()
84 85 except (NoResultFound, MultipleResultsFound, OperationalError) as e:
85 86 log.error(e)
86 87 user = None
87 88 raise formencode.Invalid(self.message('invalid_password',
88 89 state=State_obj), value, state,
89 90 error_dict=self.e_dict)
90 91 if user:
91 92 if user.active:
92 93 if user.username == username and user.password == crypted_passwd:
93 94 from pylons_app.lib.auth import AuthUser
94 95 auth_user = AuthUser()
95 96 auth_user.username = username
96 97 auth_user.is_authenticated = True
97 98 auth_user.is_admin = user.admin
98 99 auth_user.user_id = user.user_id
99 100 session['hg_app_user'] = auth_user
100 101 session.save()
101 102 log.info('user %s is now authenticated', username)
102 103
103 104 try:
104 105 user.last_login = datetime.datetime.now()
105 106 sa.add(user)
106 107 sa.commit()
107 108 except (OperationalError) as e:
108 109 log.error(e)
109 110 sa.rollback()
110 111
111 112 return value
112 113 else:
113 114 log.warning('user %s not authenticated', username)
114 115 raise formencode.Invalid(self.message('invalid_password',
115 116 state=State_obj), value, state,
116 117 error_dict=self.e_dict)
117 118 else:
118 119 log.warning('user %s is disabled', username)
119 120 raise formencode.Invalid(self.message('disabled_account',
120 121 state=State_obj),
121 122 value, state,
122 123 error_dict=self.e_dict_disable)
123 124
124 125
125 126 class ValidRepoUser(formencode.validators.FancyValidator):
126 127
127 128 def to_python(self, value, state):
128 129 sa = meta.Session
129 130 try:
130 131 self.user_db = sa.query(User)\
131 132 .filter(User.active == True)\
132 133 .filter(User.username == value).one()
133 134 except Exception:
134 135 raise formencode.Invalid(_('This username is not valid'),
135 136 value, state)
136 137 return self.user_db.user_id
137 138
138 139 def ValidRepoName(edit=False):
139 140 class _ValidRepoName(formencode.validators.FancyValidator):
140 141
141 142 def to_python(self, value, state):
142 143 slug = h.repo_name_slug(value)
143 144 if slug in ['_admin']:
144 145 raise formencode.Invalid(_('This repository name is disallowed'),
145 146 value, state)
146 147 sa = meta.Session
147 148 if sa.query(Repository).get(slug) and not edit:
148 149 raise formencode.Invalid(_('This repository already exists'),
149 150 value, state)
150 151
151 152 return slug
152 153 return _ValidRepoName
153 154
154 155 class ValidPerms(formencode.validators.FancyValidator):
155 156 messages = {'perm_new_user_name':_('This username is not valid')}
156 157
157 158 def to_python(self, value, state):
158 159 perms_update = []
159 160 perms_new = []
160 161 #build a list of permission to update and new permission to create
161 162 for k, v in value.items():
162 163 if k.startswith('perm_'):
163 164 if k.startswith('perm_new_user'):
164 165 new_perm = value.get('perm_new_user', False)
165 166 new_user = value.get('perm_new_user_name', False)
166 167 if new_user and new_perm:
167 168 if (new_user, new_perm) not in perms_new:
168 169 perms_new.append((new_user, new_perm))
169 170 else:
170 171 usr = k[5:]
171 172 if usr == 'default':
172 173 if value['private']:
173 174 #set none for default when updating to private repo
174 175 v = 'repository.none'
175 176 perms_update.append((usr, v))
176 177 value['perms_updates'] = perms_update
177 178 value['perms_new'] = perms_new
178 179 sa = meta.Session
179 180 for k, v in perms_new:
180 181 try:
181 182 self.user_db = sa.query(User)\
182 183 .filter(User.active == True)\
183 184 .filter(User.username == k).one()
184 185 except Exception:
185 186 msg = self.message('perm_new_user_name',
186 187 state=State_obj)
187 188 raise formencode.Invalid(msg, value, state, error_dict={'perm_new_user_name':msg})
188 189 return value
189 190
190 191 class ValidSettings(formencode.validators.FancyValidator):
191 192
192 193 def to_python(self, value, state):
193 194 #settings form can't edit user
194 195 if value.has_key('user'):
195 196 del['value']['user']
196 197
197 198 return value
198 199 #===============================================================================
199 200 # FORMS
200 201 #===============================================================================
201 202 class LoginForm(formencode.Schema):
202 203 allow_extra_fields = True
203 204 filter_extra_fields = True
204 205 username = UnicodeString(
205 206 strip=True,
206 207 min=3,
207 208 not_empty=True,
208 209 messages={
209 210 'empty':_('Please enter a login'),
210 211 'tooShort':_('Enter a value %(min)i characters long or more')}
211 212 )
212 213
213 214 password = UnicodeString(
214 215 strip=True,
215 216 min=3,
216 217 not_empty=True,
217 218 messages={
218 219 'empty':_('Please enter a password'),
219 220 'tooShort':_('Enter a value %(min)i characters long or more')}
220 221 )
221 222
222 223
223 224 #chained validators have access to all data
224 225 chained_validators = [ValidAuth]
225 226
226 227 def UserForm(edit=False):
227 228 class _UserForm(formencode.Schema):
228 229 allow_extra_fields = True
229 230 filter_extra_fields = True
230 231 username = All(UnicodeString(strip=True, min=3, not_empty=True), ValidUsername)
231 232 if edit:
232 233 new_password = All(UnicodeString(strip=True, min=3, not_empty=False), ValidPassword)
233 234 admin = StringBoolean(if_missing=False)
234 235 else:
235 236 password = All(UnicodeString(strip=True, min=3, not_empty=False), ValidPassword)
236 237 active = StringBoolean(if_missing=False)
237 238 name = UnicodeString(strip=True, min=3, not_empty=True)
238 239 lastname = UnicodeString(strip=True, min=3, not_empty=True)
239 240 email = Email(not_empty=True)
240 241
241 242 return _UserForm
242 243
243 244 def RepoForm(edit=False):
244 245 class _RepoForm(formencode.Schema):
245 246 allow_extra_fields = True
246 247 filter_extra_fields = False
247 248 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit))
248 249 description = UnicodeString(strip=True, min=3, not_empty=True)
249 250 private = StringBoolean(if_missing=False)
250 251
251 252 if edit:
252 253 user = All(Int(not_empty=True), ValidRepoUser)
253 254
254 255 chained_validators = [ValidPerms]
255 256 return _RepoForm
256 257
257 258 def RepoSettingsForm(edit=False):
258 259 class _RepoForm(formencode.Schema):
259 260 allow_extra_fields = True
260 261 filter_extra_fields = False
261 262 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit))
262 263 description = UnicodeString(strip=True, min=3, not_empty=True)
263 264 private = StringBoolean(if_missing=False)
264 265
265 266 chained_validators = [ValidPerms, ValidSettings]
266 267 return _RepoForm
267 268
268 269
269 270
270 271
@@ -1,91 +1,90
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 # Model for users
4 4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5 5
6 6 # This program is free software; you can redistribute it and/or
7 7 # modify it under the terms of the GNU General Public License
8 8 # as published by the Free Software Foundation; version 2
9 9 # of the License or (at your opinion) any later version of the license.
10 10 #
11 11 # This program is distributed in the hope that it will be useful,
12 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14 # GNU General Public License for more details.
15 15 #
16 16 # You should have received a copy of the GNU General Public License
17 17 # along with this program; if not, write to the Free Software
18 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 19 # MA 02110-1301, USA.
20 20
21 21 """
22 22 Created on April 9, 2010
23 23 Model for users
24 24 @author: marcink
25 25 """
26 26
27 27 from pylons_app.model.db import User
28 28 from pylons_app.model.meta import Session
29 29 from pylons.i18n.translation import _
30 30 import logging
31 31 log = logging.getLogger(__name__)
32 32
33 33 class DefaultUserException(Exception):pass
34 34
35 35 class UserModel(object):
36 36
37 37 def __init__(self):
38 38 self.sa = Session()
39 39
40 40 def get_user(self, id):
41 41 return self.sa.query(User).get(id)
42 42
43 43 def create(self, form_data):
44 44 try:
45 45 new_user = User()
46 46 for k, v in form_data.items():
47 47 setattr(new_user, k, v)
48 48
49 49 self.sa.add(new_user)
50 50 self.sa.commit()
51 51 except Exception as e:
52 52 log.error(e)
53 53 self.sa.rollback()
54 54 raise
55 55
56 56 def update(self, id, form_data):
57 57 try:
58 58 new_user = self.sa.query(User).get(id)
59 59 if new_user.username == 'default':
60 60 raise DefaultUserException(
61 61 _("You can't Edit this user since it's"
62 62 " crucial for entire application"))
63 63 for k, v in form_data.items():
64 64 if k == 'new_password' and v != '':
65
66 65 new_user.password = v
67 66 else:
68 67 setattr(new_user, k, v)
69 68
70 69 self.sa.add(new_user)
71 70 self.sa.commit()
72 71 except Exception as e:
73 72 log.error(e)
74 73 self.sa.rollback()
75 74 raise
76 75
77 76 def delete(self, id):
78 77
79 78 try:
80 79
81 80 user = self.sa.query(User).get(id)
82 81 if user.username == 'default':
83 82 raise DefaultUserException(
84 83 _("You can't remove this user since it's"
85 84 " crucial for entire application"))
86 85 self.sa.delete(user)
87 86 self.sa.commit()
88 87 except Exception as e:
89 88 log.error(e)
90 89 self.sa.rollback()
91 90 raise
General Comments 0
You need to be logged in to leave comments. Login now