comparison rhodecode/model/forms.py @ 684:7e536d1af60d beta

Code refactoring,models renames cleaned up sqlalchemy sessions, added cache support to most queries in models fixed test.ini file
author Marcin Kuzminski <marcin@python-works.com>
date Thu, 21 Oct 2010 01:38:14 +0200
parents 03676d39dd0a
children 05528ad948c4
comparison
equal deleted inserted replaced
683:dd06bdf974c8 684:7e536d1af60d
24 Email, Bool, StringBoolean 24 Email, Bool, StringBoolean
25 from pylons import session 25 from pylons import session
26 from pylons.i18n.translation import _ 26 from pylons.i18n.translation import _
27 from rhodecode.lib.auth import check_password, get_crypt_password 27 from rhodecode.lib.auth import check_password, get_crypt_password
28 from rhodecode.model import meta 28 from rhodecode.model import meta
29 from rhodecode.model.user_model import UserModel 29 from rhodecode.model.user import UserModel
30 from rhodecode.model.db import User, Repository 30 from rhodecode.model.repo import RepoModel
31 from sqlalchemy.exc import OperationalError 31 from rhodecode.model.db import User
32 from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
33 from webhelpers.pylonslib.secure_form import authentication_token 32 from webhelpers.pylonslib.secure_form import authentication_token
34 import formencode 33 import formencode
35 import logging 34 import logging
36 import os 35 import os
37 import rhodecode.lib.helpers as h 36 import rhodecode.lib.helpers as h
37
38 log = logging.getLogger(__name__) 38 log = logging.getLogger(__name__)
39
40 39
41 #this is needed to translate the messages using _() in validators 40 #this is needed to translate the messages using _() in validators
42 class State_obj(object): 41 class State_obj(object):
43 _ = staticmethod(_) 42 _ = staticmethod(_)
44 43
45 #=============================================================================== 44 #===============================================================================
46 # VALIDATORS 45 # VALIDATORS
47 #=============================================================================== 46 #===============================================================================
48 class ValidAuthToken(formencode.validators.FancyValidator): 47 class ValidAuthToken(formencode.validators.FancyValidator):
49 messages = {'invalid_token':_('Token mismatch')} 48 messages = {'invalid_token':_('Token mismatch')}
51 def validate_python(self, value, state): 50 def validate_python(self, value, state):
52 51
53 if value != authentication_token(): 52 if value != authentication_token():
54 raise formencode.Invalid(self.message('invalid_token', state, 53 raise formencode.Invalid(self.message('invalid_token', state,
55 search_number=value), value, state) 54 search_number=value), value, state)
56 55
57 def ValidUsername(edit, old_data): 56 def ValidUsername(edit, old_data):
58 class _ValidUsername(formencode.validators.FancyValidator): 57 class _ValidUsername(formencode.validators.FancyValidator):
59 58
60 def validate_python(self, value, state): 59 def validate_python(self, value, state):
61 if value in ['default', 'new_user']: 60 if value in ['default', 'new_user']:
62 raise formencode.Invalid(_('Invalid username'), value, state) 61 raise formencode.Invalid(_('Invalid username'), value, state)
63 #check if user is uniq 62 #check if user is unique
64 sa = meta.Session
65 old_un = None 63 old_un = None
66 if edit: 64 if edit:
67 old_un = sa.query(User).get(old_data.get('user_id')).username 65 old_un = UserModel().get(old_data.get('user_id')).username
68 66
69 if old_un != value or not edit: 67 if old_un != value or not edit:
70 if sa.query(User).filter(User.username == value).scalar(): 68 if UserModel().get_by_username(value, cache=False):
71 raise formencode.Invalid(_('This username already exists') , 69 raise formencode.Invalid(_('This username already exists') ,
72 value, state) 70 value, state)
73 meta.Session.remove() 71
74 72 return _ValidUsername
75 return _ValidUsername 73
76
77 class ValidPassword(formencode.validators.FancyValidator): 74 class ValidPassword(formencode.validators.FancyValidator):
78 75
79 def to_python(self, value, state): 76 def to_python(self, value, state):
80 if value: 77 if value:
81 return get_crypt_password(value) 78 return get_crypt_password(value)
82 79
83 class ValidAuth(formencode.validators.FancyValidator): 80 class ValidAuth(formencode.validators.FancyValidator):
84 messages = { 81 messages = {
85 'invalid_password':_('invalid password'), 82 'invalid_password':_('invalid password'),
86 'invalid_login':_('invalid user name'), 83 'invalid_login':_('invalid user name'),
87 'disabled_account':_('Your acccount is disabled') 84 'disabled_account':_('Your acccount is disabled')
88 85
89 } 86 }
90 #error mapping 87 #error mapping
91 e_dict = {'username':messages['invalid_login'], 88 e_dict = {'username':messages['invalid_login'],
92 'password':messages['invalid_password']} 89 'password':messages['invalid_password']}
93 e_dict_disable = {'username':messages['disabled_account']} 90 e_dict_disable = {'username':messages['disabled_account']}
94 91
95 def validate_python(self, value, state): 92 def validate_python(self, value, state):
96 password = value['password'] 93 password = value['password']
97 username = value['username'] 94 username = value['username']
98 user = UserModel().get_user_by_name(username) 95 user = UserModel().get_by_username(username)
99 if user is None: 96 if user is None:
100 raise formencode.Invalid(self.message('invalid_password', 97 raise formencode.Invalid(self.message('invalid_password',
101 state=State_obj), value, state, 98 state=State_obj), value, state,
102 error_dict=self.e_dict) 99 error_dict=self.e_dict)
103 if user: 100 if user:
104 if user.active: 101 if user.active:
105 if user.username == username and check_password(password, 102 if user.username == username and check_password(password,
106 user.password): 103 user.password):
107 return value 104 return value
114 log.warning('user %s is disabled', username) 111 log.warning('user %s is disabled', username)
115 raise formencode.Invalid(self.message('disabled_account', 112 raise formencode.Invalid(self.message('disabled_account',
116 state=State_obj), 113 state=State_obj),
117 value, state, 114 value, state,
118 error_dict=self.e_dict_disable) 115 error_dict=self.e_dict_disable)
119 116
120 class ValidRepoUser(formencode.validators.FancyValidator): 117 class ValidRepoUser(formencode.validators.FancyValidator):
121 118
122 def to_python(self, value, state): 119 def to_python(self, value, state):
120 sa = meta.Session()
123 try: 121 try:
124 self.user_db = meta.Session.query(User)\ 122 self.user_db = sa.query(User)\
125 .filter(User.active == True)\ 123 .filter(User.active == True)\
126 .filter(User.username == value).one() 124 .filter(User.username == value).one()
127 except Exception: 125 except Exception:
128 raise formencode.Invalid(_('This username is not valid'), 126 raise formencode.Invalid(_('This username is not valid'),
129 value, state) 127 value, state)
130 finally: 128 finally:
131 meta.Session.remove() 129 meta.Session.remove()
132 130
133 return self.user_db.user_id 131 return self.user_db.user_id
134 132
135 def ValidRepoName(edit, old_data): 133 def ValidRepoName(edit, old_data):
136 class _ValidRepoName(formencode.validators.FancyValidator): 134 class _ValidRepoName(formencode.validators.FancyValidator):
137 135
138 def to_python(self, value, state): 136 def to_python(self, value, state):
139 slug = h.repo_name_slug(value) 137 slug = h.repo_name_slug(value)
140 if slug in ['_admin']: 138 if slug in ['_admin']:
141 raise formencode.Invalid(_('This repository name is disallowed'), 139 raise formencode.Invalid(_('This repository name is disallowed'),
142 value, state) 140 value, state)
143 if old_data.get('repo_name') != value or not edit: 141 if old_data.get('repo_name') != value or not edit:
144 sa = meta.Session 142 if RepoModel().get(slug, cache=False):
145 if sa.query(Repository).filter(Repository.repo_name == slug).scalar():
146 raise formencode.Invalid(_('This repository already exists') , 143 raise formencode.Invalid(_('This repository already exists') ,
147 value, state) 144 value, state)
148 meta.Session.remove() 145 return slug
149 return slug 146
150 147
151
152 return _ValidRepoName 148 return _ValidRepoName
153 149
154 class ValidPerms(formencode.validators.FancyValidator): 150 class ValidPerms(formencode.validators.FancyValidator):
155 messages = {'perm_new_user_name':_('This username is not valid')} 151 messages = {'perm_new_user_name':_('This username is not valid')}
156 152
157 def to_python(self, value, state): 153 def to_python(self, value, state):
158 perms_update = [] 154 perms_update = []
159 perms_new = [] 155 perms_new = []
160 #build a list of permission to update and new permission to create 156 #build a list of permission to update and new permission to create
161 for k, v in value.items(): 157 for k, v in value.items():
165 new_user = value.get('perm_new_user_name', False) 161 new_user = value.get('perm_new_user_name', False)
166 if new_user and new_perm: 162 if new_user and new_perm:
167 if (new_user, new_perm) not in perms_new: 163 if (new_user, new_perm) not in perms_new:
168 perms_new.append((new_user, new_perm)) 164 perms_new.append((new_user, new_perm))
169 else: 165 else:
170 usr = k[5:] 166 usr = k[5:]
171 if usr == 'default': 167 if usr == 'default':
172 if value['private']: 168 if value['private']:
173 #set none for default when updating to private repo 169 #set none for default when updating to private repo
174 v = 'repository.none' 170 v = 'repository.none'
175 perms_update.append((usr, v)) 171 perms_update.append((usr, v))
182 .filter(User.active == True)\ 178 .filter(User.active == True)\
183 .filter(User.username == k).one() 179 .filter(User.username == k).one()
184 except Exception: 180 except Exception:
185 msg = self.message('perm_new_user_name', 181 msg = self.message('perm_new_user_name',
186 state=State_obj) 182 state=State_obj)
187 raise formencode.Invalid(msg, value, state, error_dict={'perm_new_user_name':msg}) 183 raise formencode.Invalid(msg, value, state, error_dict={'perm_new_user_name':msg})
188 return value 184 return value
189 185
190 class ValidSettings(formencode.validators.FancyValidator): 186 class ValidSettings(formencode.validators.FancyValidator):
191 187
192 def to_python(self, value, state): 188 def to_python(self, value, state):
193 #settings form can't edit user 189 #settings form can't edit user
194 if value.has_key('user'): 190 if value.has_key('user'):
195 del['value']['user'] 191 del['value']['user']
196 192
197 return value 193 return value
198 194
199 class ValidPath(formencode.validators.FancyValidator): 195 class ValidPath(formencode.validators.FancyValidator):
200 def to_python(self, value, state): 196 def to_python(self, value, state):
201 isdir = os.path.isdir(value.replace('*', '')) 197 isdir = os.path.isdir(value.replace('*', ''))
202 if (value.endswith('/*') or value.endswith('/**')) and isdir: 198 if (value.endswith('/*') or value.endswith('/**')) and isdir:
203 return value 199 return value
204 elif not isdir: 200 elif not isdir:
205 msg = _('This is not a valid path') 201 msg = _('This is not a valid path')
206 else: 202 else:
207 msg = _('You need to specify * or ** at the end of path (ie. /tmp/*)') 203 msg = _('You need to specify * or ** at the end of path (ie. /tmp/*)')
208 204
209 raise formencode.Invalid(msg, value, state, 205 raise formencode.Invalid(msg, value, state,
210 error_dict={'paths_root_path':msg}) 206 error_dict={'paths_root_path':msg})
211 207
212 def UniqSystemEmail(old_data): 208 def UniqSystemEmail(old_data):
213 class _UniqSystemEmail(formencode.validators.FancyValidator): 209 class _UniqSystemEmail(formencode.validators.FancyValidator):
214 def to_python(self, value, state): 210 def to_python(self, value, state):
215 if old_data.get('email') != value: 211 if old_data.get('email') != value:
216 sa = meta.Session 212 sa = meta.Session()
217 try: 213 try:
218 user = sa.query(User).filter(User.email == value).scalar() 214 user = sa.query(User).filter(User.email == value).scalar()
219 if user: 215 if user:
220 raise formencode.Invalid(_("That e-mail address is already taken") , 216 raise formencode.Invalid(_("That e-mail address is already taken") ,
221 value, state) 217 value, state)
222 finally: 218 finally:
223 meta.Session.remove() 219 meta.Session.remove()
224 220
225 return value 221 return value
226 222
227 return _UniqSystemEmail 223 return _UniqSystemEmail
228 224
229 class ValidSystemEmail(formencode.validators.FancyValidator): 225 class ValidSystemEmail(formencode.validators.FancyValidator):
230 def to_python(self, value, state): 226 def to_python(self, value, state):
231 sa = meta.Session 227 sa = meta.Session
232 try: 228 try:
233 user = sa.query(User).filter(User.email == value).scalar() 229 user = sa.query(User).filter(User.email == value).scalar()
234 if user is None: 230 if user is None:
235 raise formencode.Invalid(_("That e-mail address doesn't exist.") , 231 raise formencode.Invalid(_("That e-mail address doesn't exist.") ,
236 value, state) 232 value, state)
237 finally: 233 finally:
238 meta.Session.remove() 234 meta.Session.remove()
239 235
240 return value 236 return value
241 237
242 #=============================================================================== 238 #===============================================================================
243 # FORMS 239 # FORMS
244 #=============================================================================== 240 #===============================================================================
245 class LoginForm(formencode.Schema): 241 class LoginForm(formencode.Schema):
264 ) 260 )
265 261
266 262
267 #chained validators have access to all data 263 #chained validators have access to all data
268 chained_validators = [ValidAuth] 264 chained_validators = [ValidAuth]
269 265
270 def UserForm(edit=False, old_data={}): 266 def UserForm(edit=False, old_data={}):
271 class _UserForm(formencode.Schema): 267 class _UserForm(formencode.Schema):
272 allow_extra_fields = True 268 allow_extra_fields = True
273 filter_extra_fields = True 269 filter_extra_fields = True
274 username = All(UnicodeString(strip=True, min=1, not_empty=True), ValidUsername(edit, old_data)) 270 username = All(UnicodeString(strip=True, min=1, not_empty=True), ValidUsername(edit, old_data))
279 password = All(UnicodeString(strip=True, min=6, not_empty=True), ValidPassword) 275 password = All(UnicodeString(strip=True, min=6, not_empty=True), ValidPassword)
280 active = StringBoolean(if_missing=False) 276 active = StringBoolean(if_missing=False)
281 name = UnicodeString(strip=True, min=1, not_empty=True) 277 name = UnicodeString(strip=True, min=1, not_empty=True)
282 lastname = UnicodeString(strip=True, min=1, not_empty=True) 278 lastname = UnicodeString(strip=True, min=1, not_empty=True)
283 email = All(Email(not_empty=True), UniqSystemEmail(old_data)) 279 email = All(Email(not_empty=True), UniqSystemEmail(old_data))
284 280
285 return _UserForm 281 return _UserForm
286 282
287 RegisterForm = UserForm 283 RegisterForm = UserForm
288 284
289 def PasswordResetForm(): 285 def PasswordResetForm():
290 class _PasswordResetForm(formencode.Schema): 286 class _PasswordResetForm(formencode.Schema):
291 allow_extra_fields = True 287 allow_extra_fields = True
292 filter_extra_fields = True 288 filter_extra_fields = True
293 email = All(ValidSystemEmail(), Email(not_empty=True)) 289 email = All(ValidSystemEmail(), Email(not_empty=True))
294 return _PasswordResetForm 290 return _PasswordResetForm
295 291
296 def RepoForm(edit=False, old_data={}): 292 def RepoForm(edit=False, old_data={}):
297 class _RepoForm(formencode.Schema): 293 class _RepoForm(formencode.Schema):
298 allow_extra_fields = True 294 allow_extra_fields = True
299 filter_extra_fields = False 295 filter_extra_fields = False
300 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit, old_data)) 296 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit, old_data))
301 description = UnicodeString(strip=True, min=1, not_empty=True) 297 description = UnicodeString(strip=True, min=1, not_empty=True)
302 private = StringBoolean(if_missing=False) 298 private = StringBoolean(if_missing=False)
303 299
304 if edit: 300 if edit:
305 user = All(Int(not_empty=True), ValidRepoUser) 301 user = All(Int(not_empty=True), ValidRepoUser)
306 302
307 chained_validators = [ValidPerms] 303 chained_validators = [ValidPerms]
308 return _RepoForm 304 return _RepoForm
309 305
310 def RepoForkForm(edit=False, old_data={}): 306 def RepoForkForm(edit=False, old_data={}):
311 class _RepoForkForm(formencode.Schema): 307 class _RepoForkForm(formencode.Schema):
312 allow_extra_fields = True 308 allow_extra_fields = True
313 filter_extra_fields = False 309 filter_extra_fields = False
314 fork_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit, old_data)) 310 fork_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit, old_data))
315 description = UnicodeString(strip=True, min=1, not_empty=True) 311 description = UnicodeString(strip=True, min=1, not_empty=True)
316 private = StringBoolean(if_missing=False) 312 private = StringBoolean(if_missing=False)
317 313
318 return _RepoForkForm 314 return _RepoForkForm
319 315
320 def RepoSettingsForm(edit=False, old_data={}): 316 def RepoSettingsForm(edit=False, old_data={}):
321 class _RepoForm(formencode.Schema): 317 class _RepoForm(formencode.Schema):
322 allow_extra_fields = True 318 allow_extra_fields = True
323 filter_extra_fields = False 319 filter_extra_fields = False
324 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit, old_data)) 320 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit, old_data))
325 description = UnicodeString(strip=True, min=1, not_empty=True) 321 description = UnicodeString(strip=True, min=1, not_empty=True)
326 private = StringBoolean(if_missing=False) 322 private = StringBoolean(if_missing=False)
327 323
328 chained_validators = [ValidPerms, ValidSettings] 324 chained_validators = [ValidPerms, ValidSettings]
329 return _RepoForm 325 return _RepoForm
330 326
331 327
332 def ApplicationSettingsForm(): 328 def ApplicationSettingsForm():
333 class _ApplicationSettingsForm(formencode.Schema): 329 class _ApplicationSettingsForm(formencode.Schema):
334 allow_extra_fields = True 330 allow_extra_fields = True
335 filter_extra_fields = False 331 filter_extra_fields = False
336 rhodecode_title = UnicodeString(strip=True, min=1, not_empty=True) 332 rhodecode_title = UnicodeString(strip=True, min=1, not_empty=True)
337 rhodecode_realm = UnicodeString(strip=True, min=1, not_empty=True) 333 rhodecode_realm = UnicodeString(strip=True, min=1, not_empty=True)
338 334
339 return _ApplicationSettingsForm 335 return _ApplicationSettingsForm
340 336
341 def ApplicationUiSettingsForm(): 337 def ApplicationUiSettingsForm():
342 class _ApplicationUiSettingsForm(formencode.Schema): 338 class _ApplicationUiSettingsForm(formencode.Schema):
343 allow_extra_fields = True 339 allow_extra_fields = True
344 filter_extra_fields = False 340 filter_extra_fields = False
345 web_push_ssl = OneOf(['true', 'false'], if_missing='false') 341 web_push_ssl = OneOf(['true', 'false'], if_missing='false')
346 paths_root_path = All(ValidPath(), UnicodeString(strip=True, min=1, not_empty=True)) 342 paths_root_path = All(ValidPath(), UnicodeString(strip=True, min=1, not_empty=True))
347 hooks_changegroup_update = OneOf(['True', 'False'], if_missing=False) 343 hooks_changegroup_update = OneOf(['True', 'False'], if_missing=False)
348 hooks_changegroup_repo_size = OneOf(['True', 'False'], if_missing=False) 344 hooks_changegroup_repo_size = OneOf(['True', 'False'], if_missing=False)
349 345
350 return _ApplicationUiSettingsForm 346 return _ApplicationUiSettingsForm
351 347
352 def DefaultPermissionsForm(perms_choices, register_choices, create_choices): 348 def DefaultPermissionsForm(perms_choices, register_choices, create_choices):
353 class _DefaultPermissionsForm(formencode.Schema): 349 class _DefaultPermissionsForm(formencode.Schema):
354 allow_extra_fields = True 350 allow_extra_fields = True
355 filter_extra_fields = True 351 filter_extra_fields = True
356 overwrite_default = OneOf(['true', 'false'], if_missing='false') 352 overwrite_default = OneOf(['true', 'false'], if_missing='false')
357 default_perm = OneOf(perms_choices) 353 default_perm = OneOf(perms_choices)
358 default_register = OneOf(register_choices) 354 default_register = OneOf(register_choices)
359 default_create = OneOf(create_choices) 355 default_create = OneOf(create_choices)
360 356
361 return _DefaultPermissionsForm 357 return _DefaultPermissionsForm