Mercurial > public > src > rhodecode
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 |