##// END OF EJS Templates
fixed a bug when given wrong username at login...
marcink -
r458:00f883ab default
parent child Browse files
Show More
@@ -1,318 +1,315 b''
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 check_password, get_crypt_password
28 28 from pylons_app.model import meta
29 29 from pylons_app.model.user_model import UserModel
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 formencode
35 35 import logging
36 36 import os
37 37 import pylons_app.lib.helpers as h
38 38 log = logging.getLogger(__name__)
39 39
40 40
41 41 #this is needed to translate the messages using _() in validators
42 42 class State_obj(object):
43 43 _ = staticmethod(_)
44 44
45 45 #===============================================================================
46 46 # VALIDATORS
47 47 #===============================================================================
48 48 class ValidAuthToken(formencode.validators.FancyValidator):
49 49 messages = {'invalid_token':_('Token mismatch')}
50 50
51 51 def validate_python(self, value, state):
52 52
53 53 if value != authentication_token():
54 54 raise formencode.Invalid(self.message('invalid_token', state,
55 55 search_number=value), value, state)
56 56
57 57 def ValidUsername(edit, old_data):
58 58 class _ValidUsername(formencode.validators.FancyValidator):
59 59
60 60 def validate_python(self, value, state):
61 61 if value in ['default', 'new_user']:
62 62 raise formencode.Invalid(_('Invalid username'), value, state)
63 63 #check if user is uniq
64 64 sa = meta.Session
65 65 old_un = None
66 66 if edit:
67 67 old_un = sa.query(User).get(old_data.get('user_id')).username
68 68
69 69 if old_un != value or not edit:
70 70 if sa.query(User).filter(User.username == value).scalar():
71 71 raise formencode.Invalid(_('This username already exists') ,
72 72 value, state)
73 73 meta.Session.remove()
74 74
75 75 return _ValidUsername
76 76
77 77 class ValidPassword(formencode.validators.FancyValidator):
78 78
79 79 def to_python(self, value, state):
80 80 if value:
81 81 return get_crypt_password(value)
82 82
83 83 class ValidAuth(formencode.validators.FancyValidator):
84 84 messages = {
85 85 'invalid_password':_('invalid password'),
86 86 'invalid_login':_('invalid user name'),
87 87 'disabled_account':_('Your acccount is disabled')
88 88
89 89 }
90 90 #error mapping
91 91 e_dict = {'username':messages['invalid_login'],
92 92 'password':messages['invalid_password']}
93 93 e_dict_disable = {'username':messages['disabled_account']}
94 94
95 95 def validate_python(self, value, state):
96 96 password = value['password']
97 97 username = value['username']
98 try:
99 98 user = UserModel().get_user_by_name(username)
100 except (NoResultFound, MultipleResultsFound, OperationalError) as e:
101 log.error(e)
102 user = None
99 if user is None:
103 100 raise formencode.Invalid(self.message('invalid_password',
104 101 state=State_obj), value, state,
105 102 error_dict=self.e_dict)
106 103 if user:
107 104 if user.active:
108 105 if user.username == username and check_password(password,
109 106 user.password):
110 107 return value
111 108 else:
112 109 log.warning('user %s not authenticated', username)
113 110 raise formencode.Invalid(self.message('invalid_password',
114 111 state=State_obj), value, state,
115 112 error_dict=self.e_dict)
116 113 else:
117 114 log.warning('user %s is disabled', username)
118 115 raise formencode.Invalid(self.message('disabled_account',
119 116 state=State_obj),
120 117 value, state,
121 118 error_dict=self.e_dict_disable)
122 119
123 120 class ValidRepoUser(formencode.validators.FancyValidator):
124 121
125 122 def to_python(self, value, state):
126 123 try:
127 124 self.user_db = meta.Session.query(User)\
128 125 .filter(User.active == True)\
129 126 .filter(User.username == value).one()
130 127 except Exception:
131 128 raise formencode.Invalid(_('This username is not valid'),
132 129 value, state)
133 130 finally:
134 131 meta.Session.remove()
135 132
136 133 return self.user_db.user_id
137 134
138 135 def ValidRepoName(edit, old_data):
139 136 class _ValidRepoName(formencode.validators.FancyValidator):
140 137
141 138 def to_python(self, value, state):
142 139 slug = h.repo_name_slug(value)
143 140 if slug in ['_admin']:
144 141 raise formencode.Invalid(_('This repository name is disallowed'),
145 142 value, state)
146 143 if old_data.get('repo_name') != value or not edit:
147 144 sa = meta.Session
148 145 if sa.query(Repository).filter(Repository.repo_name == slug).scalar():
149 146 raise formencode.Invalid(_('This repository already exists') ,
150 147 value, state)
151 148 meta.Session.remove()
152 149 return slug
153 150
154 151
155 152 return _ValidRepoName
156 153
157 154 class ValidPerms(formencode.validators.FancyValidator):
158 155 messages = {'perm_new_user_name':_('This username is not valid')}
159 156
160 157 def to_python(self, value, state):
161 158 perms_update = []
162 159 perms_new = []
163 160 #build a list of permission to update and new permission to create
164 161 for k, v in value.items():
165 162 if k.startswith('perm_'):
166 163 if k.startswith('perm_new_user'):
167 164 new_perm = value.get('perm_new_user', False)
168 165 new_user = value.get('perm_new_user_name', False)
169 166 if new_user and new_perm:
170 167 if (new_user, new_perm) not in perms_new:
171 168 perms_new.append((new_user, new_perm))
172 169 else:
173 170 usr = k[5:]
174 171 if usr == 'default':
175 172 if value['private']:
176 173 #set none for default when updating to private repo
177 174 v = 'repository.none'
178 175 perms_update.append((usr, v))
179 176 value['perms_updates'] = perms_update
180 177 value['perms_new'] = perms_new
181 178 sa = meta.Session
182 179 for k, v in perms_new:
183 180 try:
184 181 self.user_db = sa.query(User)\
185 182 .filter(User.active == True)\
186 183 .filter(User.username == k).one()
187 184 except Exception:
188 185 msg = self.message('perm_new_user_name',
189 186 state=State_obj)
190 187 raise formencode.Invalid(msg, value, state, error_dict={'perm_new_user_name':msg})
191 188 return value
192 189
193 190 class ValidSettings(formencode.validators.FancyValidator):
194 191
195 192 def to_python(self, value, state):
196 193 #settings form can't edit user
197 194 if value.has_key('user'):
198 195 del['value']['user']
199 196
200 197 return value
201 198
202 199 class ValidPath(formencode.validators.FancyValidator):
203 200 def to_python(self, value, state):
204 201 isdir = os.path.isdir(value.replace('*', ''))
205 202 if (value.endswith('/*') or value.endswith('/**')) and isdir:
206 203 return value
207 204 elif not isdir:
208 205 msg = _('This is not a valid path')
209 206 else:
210 207 msg = _('You need to specify * or ** at the end of path (ie. /tmp/*)')
211 208
212 209 raise formencode.Invalid(msg, value, state,
213 210 error_dict={'paths_root_path':msg})
214 211
215 212 #===============================================================================
216 213 # FORMS
217 214 #===============================================================================
218 215 class LoginForm(formencode.Schema):
219 216 allow_extra_fields = True
220 217 filter_extra_fields = True
221 218 username = UnicodeString(
222 219 strip=True,
223 220 min=3,
224 221 not_empty=True,
225 222 messages={
226 223 'empty':_('Please enter a login'),
227 224 'tooShort':_('Enter a value %(min)i characters long or more')}
228 225 )
229 226
230 227 password = UnicodeString(
231 228 strip=True,
232 229 min=3,
233 230 not_empty=True,
234 231 messages={
235 232 'empty':_('Please enter a password'),
236 233 'tooShort':_('Enter a value %(min)i characters long or more')}
237 234 )
238 235
239 236
240 237 #chained validators have access to all data
241 238 chained_validators = [ValidAuth]
242 239
243 240 def UserForm(edit=False, old_data={}):
244 241 class _UserForm(formencode.Schema):
245 242 allow_extra_fields = True
246 243 filter_extra_fields = True
247 244 username = All(UnicodeString(strip=True, min=3, not_empty=True), ValidUsername(edit, old_data))
248 245 if edit:
249 246 new_password = All(UnicodeString(strip=True, min=3, not_empty=False), ValidPassword)
250 247 admin = StringBoolean(if_missing=False)
251 248 else:
252 249 password = All(UnicodeString(strip=True, min=8, not_empty=True), ValidPassword)
253 250 active = StringBoolean(if_missing=False)
254 251 name = UnicodeString(strip=True, min=3, not_empty=True)
255 252 lastname = UnicodeString(strip=True, min=3, not_empty=True)
256 253 email = Email(not_empty=True)
257 254
258 255 return _UserForm
259 256
260 257 RegisterForm = UserForm
261 258
262 259
263 260 def RepoForm(edit=False, old_data={}):
264 261 class _RepoForm(formencode.Schema):
265 262 allow_extra_fields = True
266 263 filter_extra_fields = False
267 264 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit, old_data))
268 265 description = UnicodeString(strip=True, min=3, not_empty=True)
269 266 private = StringBoolean(if_missing=False)
270 267
271 268 if edit:
272 269 user = All(Int(not_empty=True), ValidRepoUser)
273 270
274 271 chained_validators = [ValidPerms]
275 272 return _RepoForm
276 273
277 274 def RepoSettingsForm(edit=False, old_data={}):
278 275 class _RepoForm(formencode.Schema):
279 276 allow_extra_fields = True
280 277 filter_extra_fields = False
281 278 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit, old_data))
282 279 description = UnicodeString(strip=True, min=3, not_empty=True)
283 280 private = StringBoolean(if_missing=False)
284 281
285 282 chained_validators = [ValidPerms, ValidSettings]
286 283 return _RepoForm
287 284
288 285
289 286 def ApplicationSettingsForm():
290 287 class _ApplicationSettingsForm(formencode.Schema):
291 288 allow_extra_fields = True
292 289 filter_extra_fields = False
293 290 hg_app_title = UnicodeString(strip=True, min=3, not_empty=True)
294 291 hg_app_realm = UnicodeString(strip=True, min=3, not_empty=True)
295 292
296 293 return _ApplicationSettingsForm
297 294
298 295 def ApplicationUiSettingsForm():
299 296 class _ApplicationUiSettingsForm(formencode.Schema):
300 297 allow_extra_fields = True
301 298 filter_extra_fields = False
302 299 web_push_ssl = OneOf(['true', 'false'], if_missing='false')
303 300 paths_root_path = All(ValidPath(), UnicodeString(strip=True, min=3, not_empty=True))
304 301 hooks_changegroup_update = OneOf(['True', 'False'], if_missing=False)
305 302 hooks_changegroup_repo_size = OneOf(['True', 'False'], if_missing=False)
306 303
307 304 return _ApplicationUiSettingsForm
308 305
309 306 def DefaultPermissionsForm(perms_choices, register_choices, create_choices):
310 307 class _DefaultPermissionsForm(formencode.Schema):
311 308 allow_extra_fields = True
312 309 filter_extra_fields = True
313 310 overwrite_default = OneOf(['true', 'false'], if_missing='false')
314 311 default_perm = OneOf(perms_choices)
315 312 default_register = OneOf(register_choices)
316 313 default_create = OneOf(create_choices)
317 314
318 315 return _DefaultPermissionsForm
General Comments 0
You need to be logged in to leave comments. Login now