##// END OF EJS Templates
fixed hardcoded admin prefix check in forms
marcink -
r1533:c0e60575 beta
parent child Browse files
Show More
@@ -1,680 +1,681 b''
1 """ this is forms validation classes
1 """ this is forms validation classes
2 http://formencode.org/module-formencode.validators.html
2 http://formencode.org/module-formencode.validators.html
3 for list off all availible validators
3 for list off all availible validators
4
4
5 we can create our own validators
5 we can create our own validators
6
6
7 The table below outlines the options which can be used in a schema in addition to the validators themselves
7 The table below outlines the options which can be used in a schema in addition to the validators themselves
8 pre_validators [] These validators will be applied before the schema
8 pre_validators [] These validators will be applied before the schema
9 chained_validators [] These validators will be applied after the schema
9 chained_validators [] These validators will be applied after the schema
10 allow_extra_fields False If True, then it is not an error when keys that aren't associated with a validator are present
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 filter_extra_fields False If True, then keys that aren't associated with a validator are removed
11 filter_extra_fields False If True, then keys that aren't associated with a validator are removed
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.
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 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
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 <name> = formencode.validators.<name of validator>
16 <name> = formencode.validators.<name of validator>
17 <name> must equal form name
17 <name> must equal form name
18 list=[1,2,3,4,5]
18 list=[1,2,3,4,5]
19 for SELECT use formencode.All(OneOf(list), Int())
19 for SELECT use formencode.All(OneOf(list), Int())
20
20
21 """
21 """
22 import os
22 import os
23 import re
23 import re
24 import logging
24 import logging
25 import traceback
25 import traceback
26
26
27 import formencode
27 import formencode
28 from formencode import All
28 from formencode import All
29 from formencode.validators import UnicodeString, OneOf, Int, Number, Regex, \
29 from formencode.validators import UnicodeString, OneOf, Int, Number, Regex, \
30 Email, Bool, StringBoolean, Set
30 Email, Bool, StringBoolean, Set
31
31
32 from pylons.i18n.translation import _
32 from pylons.i18n.translation import _
33 from webhelpers.pylonslib.secure_form import authentication_token
33 from webhelpers.pylonslib.secure_form import authentication_token
34
34
35 from rhodecode.config.routing import ADMIN_PREFIX
35 from rhodecode.lib.utils import repo_name_slug
36 from rhodecode.lib.utils import repo_name_slug
36 from rhodecode.lib.auth import authenticate, get_crypt_password
37 from rhodecode.lib.auth import authenticate, get_crypt_password
37 from rhodecode.lib.exceptions import LdapImportError
38 from rhodecode.lib.exceptions import LdapImportError
38 from rhodecode.model.user import UserModel
39 from rhodecode.model.user import UserModel
39 from rhodecode.model.repo import RepoModel
40 from rhodecode.model.repo import RepoModel
40 from rhodecode.model.db import User, UsersGroup, Group
41 from rhodecode.model.db import User, UsersGroup, Group
41 from rhodecode import BACKENDS
42 from rhodecode import BACKENDS
42
43
43 log = logging.getLogger(__name__)
44 log = logging.getLogger(__name__)
44
45
45 #this is needed to translate the messages using _() in validators
46 #this is needed to translate the messages using _() in validators
46 class State_obj(object):
47 class State_obj(object):
47 _ = staticmethod(_)
48 _ = staticmethod(_)
48
49
49 #==============================================================================
50 #==============================================================================
50 # VALIDATORS
51 # VALIDATORS
51 #==============================================================================
52 #==============================================================================
52 class ValidAuthToken(formencode.validators.FancyValidator):
53 class ValidAuthToken(formencode.validators.FancyValidator):
53 messages = {'invalid_token':_('Token mismatch')}
54 messages = {'invalid_token':_('Token mismatch')}
54
55
55 def validate_python(self, value, state):
56 def validate_python(self, value, state):
56
57
57 if value != authentication_token():
58 if value != authentication_token():
58 raise formencode.Invalid(self.message('invalid_token', state,
59 raise formencode.Invalid(self.message('invalid_token', state,
59 search_number=value), value, state)
60 search_number=value), value, state)
60
61
61 def ValidUsername(edit, old_data):
62 def ValidUsername(edit, old_data):
62 class _ValidUsername(formencode.validators.FancyValidator):
63 class _ValidUsername(formencode.validators.FancyValidator):
63
64
64 def validate_python(self, value, state):
65 def validate_python(self, value, state):
65 if value in ['default', 'new_user']:
66 if value in ['default', 'new_user']:
66 raise formencode.Invalid(_('Invalid username'), value, state)
67 raise formencode.Invalid(_('Invalid username'), value, state)
67 #check if user is unique
68 #check if user is unique
68 old_un = None
69 old_un = None
69 if edit:
70 if edit:
70 old_un = UserModel().get(old_data.get('user_id')).username
71 old_un = UserModel().get(old_data.get('user_id')).username
71
72
72 if old_un != value or not edit:
73 if old_un != value or not edit:
73 if User.get_by_username(value, case_insensitive=True):
74 if User.get_by_username(value, case_insensitive=True):
74 raise formencode.Invalid(_('This username already '
75 raise formencode.Invalid(_('This username already '
75 'exists') , value, state)
76 'exists') , value, state)
76
77
77 if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None:
78 if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None:
78 raise formencode.Invalid(_('Username may only contain '
79 raise formencode.Invalid(_('Username may only contain '
79 'alphanumeric characters '
80 'alphanumeric characters '
80 'underscores, periods or dashes '
81 'underscores, periods or dashes '
81 'and must begin with alphanumeric '
82 'and must begin with alphanumeric '
82 'character'), value, state)
83 'character'), value, state)
83
84
84 return _ValidUsername
85 return _ValidUsername
85
86
86
87
87 def ValidUsersGroup(edit, old_data):
88 def ValidUsersGroup(edit, old_data):
88
89
89 class _ValidUsersGroup(formencode.validators.FancyValidator):
90 class _ValidUsersGroup(formencode.validators.FancyValidator):
90
91
91 def validate_python(self, value, state):
92 def validate_python(self, value, state):
92 if value in ['default']:
93 if value in ['default']:
93 raise formencode.Invalid(_('Invalid group name'), value, state)
94 raise formencode.Invalid(_('Invalid group name'), value, state)
94 #check if group is unique
95 #check if group is unique
95 old_ugname = None
96 old_ugname = None
96 if edit:
97 if edit:
97 old_ugname = UsersGroup.get(
98 old_ugname = UsersGroup.get(
98 old_data.get('users_group_id')).users_group_name
99 old_data.get('users_group_id')).users_group_name
99
100
100 if old_ugname != value or not edit:
101 if old_ugname != value or not edit:
101 if UsersGroup.get_by_group_name(value, cache=False,
102 if UsersGroup.get_by_group_name(value, cache=False,
102 case_insensitive=True):
103 case_insensitive=True):
103 raise formencode.Invalid(_('This users group '
104 raise formencode.Invalid(_('This users group '
104 'already exists') , value,
105 'already exists') , value,
105 state)
106 state)
106
107
107
108
108 if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None:
109 if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None:
109 raise formencode.Invalid(_('Group name may only contain '
110 raise formencode.Invalid(_('Group name may only contain '
110 'alphanumeric characters '
111 'alphanumeric characters '
111 'underscores, periods or dashes '
112 'underscores, periods or dashes '
112 'and must begin with alphanumeric '
113 'and must begin with alphanumeric '
113 'character'), value, state)
114 'character'), value, state)
114
115
115 return _ValidUsersGroup
116 return _ValidUsersGroup
116
117
117
118
118 def ValidReposGroup(edit, old_data):
119 def ValidReposGroup(edit, old_data):
119 class _ValidReposGroup(formencode.validators.FancyValidator):
120 class _ValidReposGroup(formencode.validators.FancyValidator):
120
121
121 def validate_python(self, value, state):
122 def validate_python(self, value, state):
122 #TODO WRITE VALIDATIONS
123 #TODO WRITE VALIDATIONS
123 group_name = value.get('group_name')
124 group_name = value.get('group_name')
124 group_parent_id = int(value.get('group_parent_id') or - 1)
125 group_parent_id = int(value.get('group_parent_id') or - 1)
125
126
126 # slugify repo group just in case :)
127 # slugify repo group just in case :)
127 slug = repo_name_slug(group_name)
128 slug = repo_name_slug(group_name)
128
129
129 # check for parent of self
130 # check for parent of self
130 if edit and old_data['group_id'] == group_parent_id:
131 if edit and old_data['group_id'] == group_parent_id:
131 e_dict = {'group_parent_id':_('Cannot assign this group '
132 e_dict = {'group_parent_id':_('Cannot assign this group '
132 'as parent')}
133 'as parent')}
133 raise formencode.Invalid('', value, state,
134 raise formencode.Invalid('', value, state,
134 error_dict=e_dict)
135 error_dict=e_dict)
135
136
136 old_gname = None
137 old_gname = None
137 if edit:
138 if edit:
138 old_gname = Group.get(
139 old_gname = Group.get(
139 old_data.get('group_id')).group_name
140 old_data.get('group_id')).group_name
140
141
141 if old_gname != group_name or not edit:
142 if old_gname != group_name or not edit:
142 # check filesystem
143 # check filesystem
143 gr = Group.query().filter(Group.group_name == slug)\
144 gr = Group.query().filter(Group.group_name == slug)\
144 .filter(Group.group_parent_id == group_parent_id).scalar()
145 .filter(Group.group_parent_id == group_parent_id).scalar()
145
146
146 if gr:
147 if gr:
147 e_dict = {'group_name':_('This group already exists')}
148 e_dict = {'group_name':_('This group already exists')}
148 raise formencode.Invalid('', value, state,
149 raise formencode.Invalid('', value, state,
149 error_dict=e_dict)
150 error_dict=e_dict)
150
151
151 return _ValidReposGroup
152 return _ValidReposGroup
152
153
153 class ValidPassword(formencode.validators.FancyValidator):
154 class ValidPassword(formencode.validators.FancyValidator):
154
155
155 def to_python(self, value, state):
156 def to_python(self, value, state):
156
157
157 if value:
158 if value:
158
159
159 if value.get('password'):
160 if value.get('password'):
160 try:
161 try:
161 value['password'] = get_crypt_password(value['password'])
162 value['password'] = get_crypt_password(value['password'])
162 except UnicodeEncodeError:
163 except UnicodeEncodeError:
163 e_dict = {'password':_('Invalid characters in password')}
164 e_dict = {'password':_('Invalid characters in password')}
164 raise formencode.Invalid('', value, state, error_dict=e_dict)
165 raise formencode.Invalid('', value, state, error_dict=e_dict)
165
166
166 if value.get('password_confirmation'):
167 if value.get('password_confirmation'):
167 try:
168 try:
168 value['password_confirmation'] = \
169 value['password_confirmation'] = \
169 get_crypt_password(value['password_confirmation'])
170 get_crypt_password(value['password_confirmation'])
170 except UnicodeEncodeError:
171 except UnicodeEncodeError:
171 e_dict = {'password_confirmation':_('Invalid characters in password')}
172 e_dict = {'password_confirmation':_('Invalid characters in password')}
172 raise formencode.Invalid('', value, state, error_dict=e_dict)
173 raise formencode.Invalid('', value, state, error_dict=e_dict)
173
174
174 if value.get('new_password'):
175 if value.get('new_password'):
175 try:
176 try:
176 value['new_password'] = \
177 value['new_password'] = \
177 get_crypt_password(value['new_password'])
178 get_crypt_password(value['new_password'])
178 except UnicodeEncodeError:
179 except UnicodeEncodeError:
179 e_dict = {'new_password':_('Invalid characters in password')}
180 e_dict = {'new_password':_('Invalid characters in password')}
180 raise formencode.Invalid('', value, state, error_dict=e_dict)
181 raise formencode.Invalid('', value, state, error_dict=e_dict)
181
182
182 return value
183 return value
183
184
184 class ValidPasswordsMatch(formencode.validators.FancyValidator):
185 class ValidPasswordsMatch(formencode.validators.FancyValidator):
185
186
186 def validate_python(self, value, state):
187 def validate_python(self, value, state):
187
188
188 if value['password'] != value['password_confirmation']:
189 if value['password'] != value['password_confirmation']:
189 e_dict = {'password_confirmation':
190 e_dict = {'password_confirmation':
190 _('Passwords do not match')}
191 _('Passwords do not match')}
191 raise formencode.Invalid('', value, state, error_dict=e_dict)
192 raise formencode.Invalid('', value, state, error_dict=e_dict)
192
193
193 class ValidAuth(formencode.validators.FancyValidator):
194 class ValidAuth(formencode.validators.FancyValidator):
194 messages = {
195 messages = {
195 'invalid_password':_('invalid password'),
196 'invalid_password':_('invalid password'),
196 'invalid_login':_('invalid user name'),
197 'invalid_login':_('invalid user name'),
197 'disabled_account':_('Your account is disabled')
198 'disabled_account':_('Your account is disabled')
198
199
199 }
200 }
200 #error mapping
201 #error mapping
201 e_dict = {'username':messages['invalid_login'],
202 e_dict = {'username':messages['invalid_login'],
202 'password':messages['invalid_password']}
203 'password':messages['invalid_password']}
203 e_dict_disable = {'username':messages['disabled_account']}
204 e_dict_disable = {'username':messages['disabled_account']}
204
205
205 def validate_python(self, value, state):
206 def validate_python(self, value, state):
206 password = value['password']
207 password = value['password']
207 username = value['username']
208 username = value['username']
208 user = User.get_by_username(username)
209 user = User.get_by_username(username)
209
210
210 if authenticate(username, password):
211 if authenticate(username, password):
211 return value
212 return value
212 else:
213 else:
213 if user and user.active is False:
214 if user and user.active is False:
214 log.warning('user %s is disabled', username)
215 log.warning('user %s is disabled', username)
215 raise formencode.Invalid(self.message('disabled_account',
216 raise formencode.Invalid(self.message('disabled_account',
216 state=State_obj),
217 state=State_obj),
217 value, state,
218 value, state,
218 error_dict=self.e_dict_disable)
219 error_dict=self.e_dict_disable)
219 else:
220 else:
220 log.warning('user %s not authenticated', username)
221 log.warning('user %s not authenticated', username)
221 raise formencode.Invalid(self.message('invalid_password',
222 raise formencode.Invalid(self.message('invalid_password',
222 state=State_obj), value, state,
223 state=State_obj), value, state,
223 error_dict=self.e_dict)
224 error_dict=self.e_dict)
224
225
225 class ValidRepoUser(formencode.validators.FancyValidator):
226 class ValidRepoUser(formencode.validators.FancyValidator):
226
227
227 def to_python(self, value, state):
228 def to_python(self, value, state):
228 try:
229 try:
229 User.query().filter(User.active == True)\
230 User.query().filter(User.active == True)\
230 .filter(User.username == value).one()
231 .filter(User.username == value).one()
231 except Exception:
232 except Exception:
232 raise formencode.Invalid(_('This username is not valid'),
233 raise formencode.Invalid(_('This username is not valid'),
233 value, state)
234 value, state)
234 return value
235 return value
235
236
236 def ValidRepoName(edit, old_data):
237 def ValidRepoName(edit, old_data):
237 class _ValidRepoName(formencode.validators.FancyValidator):
238 class _ValidRepoName(formencode.validators.FancyValidator):
238 def to_python(self, value, state):
239 def to_python(self, value, state):
239
240
240 repo_name = value.get('repo_name')
241 repo_name = value.get('repo_name')
241
242
242 slug = repo_name_slug(repo_name)
243 slug = repo_name_slug(repo_name)
243 if slug in ['_admin', '']:
244 if slug in [ADMIN_PREFIX, '']:
244 e_dict = {'repo_name': _('This repository name is disallowed')}
245 e_dict = {'repo_name': _('This repository name is disallowed')}
245 raise formencode.Invalid('', value, state, error_dict=e_dict)
246 raise formencode.Invalid('', value, state, error_dict=e_dict)
246
247
247
248
248 if value.get('repo_group'):
249 if value.get('repo_group'):
249 gr = Group.get(value.get('repo_group'))
250 gr = Group.get(value.get('repo_group'))
250 group_path = gr.full_path
251 group_path = gr.full_path
251 # value needs to be aware of group name in order to check
252 # value needs to be aware of group name in order to check
252 # db key This is an actuall just the name to store in the
253 # db key This is an actuall just the name to store in the
253 # database
254 # database
254 repo_name_full = group_path + Group.url_sep() + repo_name
255 repo_name_full = group_path + Group.url_sep() + repo_name
255 else:
256 else:
256 group_path = ''
257 group_path = ''
257 repo_name_full = repo_name
258 repo_name_full = repo_name
258
259
259
260
260 value['repo_name_full'] = repo_name_full
261 value['repo_name_full'] = repo_name_full
261 if old_data.get('repo_name') != repo_name_full or not edit:
262 if old_data.get('repo_name') != repo_name_full or not edit:
262
263
263 if group_path != '':
264 if group_path != '':
264 if RepoModel().get_by_repo_name(repo_name_full,):
265 if RepoModel().get_by_repo_name(repo_name_full,):
265 e_dict = {'repo_name':_('This repository already '
266 e_dict = {'repo_name':_('This repository already '
266 'exists in group "%s"') %
267 'exists in group "%s"') %
267 gr.group_name}
268 gr.group_name}
268 raise formencode.Invalid('', value, state,
269 raise formencode.Invalid('', value, state,
269 error_dict=e_dict)
270 error_dict=e_dict)
270
271
271 else:
272 else:
272 if RepoModel().get_by_repo_name(repo_name_full):
273 if RepoModel().get_by_repo_name(repo_name_full):
273 e_dict = {'repo_name':_('This repository '
274 e_dict = {'repo_name':_('This repository '
274 'already exists')}
275 'already exists')}
275 raise formencode.Invalid('', value, state,
276 raise formencode.Invalid('', value, state,
276 error_dict=e_dict)
277 error_dict=e_dict)
277 return value
278 return value
278
279
279
280
280 return _ValidRepoName
281 return _ValidRepoName
281
282
282 def ValidForkName():
283 def ValidForkName():
283 class _ValidForkName(formencode.validators.FancyValidator):
284 class _ValidForkName(formencode.validators.FancyValidator):
284 def to_python(self, value, state):
285 def to_python(self, value, state):
285
286
286 repo_name = value.get('fork_name')
287 repo_name = value.get('fork_name')
287
288
288 slug = repo_name_slug(repo_name)
289 slug = repo_name_slug(repo_name)
289 if slug in ['_admin', '']:
290 if slug in [ADMIN_PREFIX, '']:
290 e_dict = {'repo_name': _('This repository name is disallowed')}
291 e_dict = {'repo_name': _('This repository name is disallowed')}
291 raise formencode.Invalid('', value, state, error_dict=e_dict)
292 raise formencode.Invalid('', value, state, error_dict=e_dict)
292
293
293 if RepoModel().get_by_repo_name(repo_name):
294 if RepoModel().get_by_repo_name(repo_name):
294 e_dict = {'fork_name':_('This repository '
295 e_dict = {'fork_name':_('This repository '
295 'already exists')}
296 'already exists')}
296 raise formencode.Invalid('', value, state,
297 raise formencode.Invalid('', value, state,
297 error_dict=e_dict)
298 error_dict=e_dict)
298 return value
299 return value
299 return _ValidForkName
300 return _ValidForkName
300
301
301
302
302 def SlugifyName():
303 def SlugifyName():
303 class _SlugifyName(formencode.validators.FancyValidator):
304 class _SlugifyName(formencode.validators.FancyValidator):
304
305
305 def to_python(self, value, state):
306 def to_python(self, value, state):
306 return repo_name_slug(value)
307 return repo_name_slug(value)
307
308
308 return _SlugifyName
309 return _SlugifyName
309
310
310 def ValidCloneUri():
311 def ValidCloneUri():
311 from mercurial.httprepo import httprepository, httpsrepository
312 from mercurial.httprepo import httprepository, httpsrepository
312 from rhodecode.lib.utils import make_ui
313 from rhodecode.lib.utils import make_ui
313
314
314 class _ValidCloneUri(formencode.validators.FancyValidator):
315 class _ValidCloneUri(formencode.validators.FancyValidator):
315
316
316 def to_python(self, value, state):
317 def to_python(self, value, state):
317 if not value:
318 if not value:
318 pass
319 pass
319 elif value.startswith('https'):
320 elif value.startswith('https'):
320 try:
321 try:
321 httpsrepository(make_ui('db'), value).capabilities
322 httpsrepository(make_ui('db'), value).capabilities
322 except Exception, e:
323 except Exception, e:
323 log.error(traceback.format_exc())
324 log.error(traceback.format_exc())
324 raise formencode.Invalid(_('invalid clone url'), value,
325 raise formencode.Invalid(_('invalid clone url'), value,
325 state)
326 state)
326 elif value.startswith('http'):
327 elif value.startswith('http'):
327 try:
328 try:
328 httprepository(make_ui('db'), value).capabilities
329 httprepository(make_ui('db'), value).capabilities
329 except Exception, e:
330 except Exception, e:
330 log.error(traceback.format_exc())
331 log.error(traceback.format_exc())
331 raise formencode.Invalid(_('invalid clone url'), value,
332 raise formencode.Invalid(_('invalid clone url'), value,
332 state)
333 state)
333 else:
334 else:
334 raise formencode.Invalid(_('Invalid clone url, provide a '
335 raise formencode.Invalid(_('Invalid clone url, provide a '
335 'valid clone http\s url'), value,
336 'valid clone http\s url'), value,
336 state)
337 state)
337 return value
338 return value
338
339
339 return _ValidCloneUri
340 return _ValidCloneUri
340
341
341 def ValidForkType(old_data):
342 def ValidForkType(old_data):
342 class _ValidForkType(formencode.validators.FancyValidator):
343 class _ValidForkType(formencode.validators.FancyValidator):
343
344
344 def to_python(self, value, state):
345 def to_python(self, value, state):
345 if old_data['repo_type'] != value:
346 if old_data['repo_type'] != value:
346 raise formencode.Invalid(_('Fork have to be the same '
347 raise formencode.Invalid(_('Fork have to be the same '
347 'type as original'), value, state)
348 'type as original'), value, state)
348
349
349 return value
350 return value
350 return _ValidForkType
351 return _ValidForkType
351
352
352 class ValidPerms(formencode.validators.FancyValidator):
353 class ValidPerms(formencode.validators.FancyValidator):
353 messages = {'perm_new_member_name':_('This username or users group name'
354 messages = {'perm_new_member_name':_('This username or users group name'
354 ' is not valid')}
355 ' is not valid')}
355
356
356 def to_python(self, value, state):
357 def to_python(self, value, state):
357 perms_update = []
358 perms_update = []
358 perms_new = []
359 perms_new = []
359 #build a list of permission to update and new permission to create
360 #build a list of permission to update and new permission to create
360 for k, v in value.items():
361 for k, v in value.items():
361 #means new added member to permissions
362 #means new added member to permissions
362 if k.startswith('perm_new_member'):
363 if k.startswith('perm_new_member'):
363 new_perm = value.get('perm_new_member', False)
364 new_perm = value.get('perm_new_member', False)
364 new_member = value.get('perm_new_member_name', False)
365 new_member = value.get('perm_new_member_name', False)
365 new_type = value.get('perm_new_member_type')
366 new_type = value.get('perm_new_member_type')
366
367
367 if new_member and new_perm:
368 if new_member and new_perm:
368 if (new_member, new_perm, new_type) not in perms_new:
369 if (new_member, new_perm, new_type) not in perms_new:
369 perms_new.append((new_member, new_perm, new_type))
370 perms_new.append((new_member, new_perm, new_type))
370 elif k.startswith('u_perm_') or k.startswith('g_perm_'):
371 elif k.startswith('u_perm_') or k.startswith('g_perm_'):
371 member = k[7:]
372 member = k[7:]
372 t = {'u':'user',
373 t = {'u':'user',
373 'g':'users_group'}[k[0]]
374 'g':'users_group'}[k[0]]
374 if member == 'default':
375 if member == 'default':
375 if value['private']:
376 if value['private']:
376 #set none for default when updating to private repo
377 #set none for default when updating to private repo
377 v = 'repository.none'
378 v = 'repository.none'
378 perms_update.append((member, v, t))
379 perms_update.append((member, v, t))
379
380
380 value['perms_updates'] = perms_update
381 value['perms_updates'] = perms_update
381 value['perms_new'] = perms_new
382 value['perms_new'] = perms_new
382
383
383 #update permissions
384 #update permissions
384 for k, v, t in perms_new:
385 for k, v, t in perms_new:
385 try:
386 try:
386 if t is 'user':
387 if t is 'user':
387 self.user_db = User.query()\
388 self.user_db = User.query()\
388 .filter(User.active == True)\
389 .filter(User.active == True)\
389 .filter(User.username == k).one()
390 .filter(User.username == k).one()
390 if t is 'users_group':
391 if t is 'users_group':
391 self.user_db = UsersGroup.query()\
392 self.user_db = UsersGroup.query()\
392 .filter(UsersGroup.users_group_active == True)\
393 .filter(UsersGroup.users_group_active == True)\
393 .filter(UsersGroup.users_group_name == k).one()
394 .filter(UsersGroup.users_group_name == k).one()
394
395
395 except Exception:
396 except Exception:
396 msg = self.message('perm_new_member_name',
397 msg = self.message('perm_new_member_name',
397 state=State_obj)
398 state=State_obj)
398 raise formencode.Invalid(msg, value, state,
399 raise formencode.Invalid(msg, value, state,
399 error_dict={'perm_new_member_name':msg})
400 error_dict={'perm_new_member_name':msg})
400 return value
401 return value
401
402
402 class ValidSettings(formencode.validators.FancyValidator):
403 class ValidSettings(formencode.validators.FancyValidator):
403
404
404 def to_python(self, value, state):
405 def to_python(self, value, state):
405 #settings form can't edit user
406 #settings form can't edit user
406 if value.has_key('user'):
407 if value.has_key('user'):
407 del['value']['user']
408 del['value']['user']
408
409
409 return value
410 return value
410
411
411 class ValidPath(formencode.validators.FancyValidator):
412 class ValidPath(formencode.validators.FancyValidator):
412 def to_python(self, value, state):
413 def to_python(self, value, state):
413
414
414 if not os.path.isdir(value):
415 if not os.path.isdir(value):
415 msg = _('This is not a valid path')
416 msg = _('This is not a valid path')
416 raise formencode.Invalid(msg, value, state,
417 raise formencode.Invalid(msg, value, state,
417 error_dict={'paths_root_path':msg})
418 error_dict={'paths_root_path':msg})
418 return value
419 return value
419
420
420 def UniqSystemEmail(old_data):
421 def UniqSystemEmail(old_data):
421 class _UniqSystemEmail(formencode.validators.FancyValidator):
422 class _UniqSystemEmail(formencode.validators.FancyValidator):
422 def to_python(self, value, state):
423 def to_python(self, value, state):
423 value = value.lower()
424 value = value.lower()
424 if old_data.get('email') != value:
425 if old_data.get('email') != value:
425 user = User.query().filter(User.email == value).scalar()
426 user = User.query().filter(User.email == value).scalar()
426 if user:
427 if user:
427 raise formencode.Invalid(
428 raise formencode.Invalid(
428 _("This e-mail address is already taken"),
429 _("This e-mail address is already taken"),
429 value, state)
430 value, state)
430 return value
431 return value
431
432
432 return _UniqSystemEmail
433 return _UniqSystemEmail
433
434
434 class ValidSystemEmail(formencode.validators.FancyValidator):
435 class ValidSystemEmail(formencode.validators.FancyValidator):
435 def to_python(self, value, state):
436 def to_python(self, value, state):
436 value = value.lower()
437 value = value.lower()
437 user = User.query().filter(User.email == value).scalar()
438 user = User.query().filter(User.email == value).scalar()
438 if user is None:
439 if user is None:
439 raise formencode.Invalid(_("This e-mail address doesn't exist.") ,
440 raise formencode.Invalid(_("This e-mail address doesn't exist.") ,
440 value, state)
441 value, state)
441
442
442 return value
443 return value
443
444
444 class LdapLibValidator(formencode.validators.FancyValidator):
445 class LdapLibValidator(formencode.validators.FancyValidator):
445
446
446 def to_python(self, value, state):
447 def to_python(self, value, state):
447
448
448 try:
449 try:
449 import ldap
450 import ldap
450 except ImportError:
451 except ImportError:
451 raise LdapImportError
452 raise LdapImportError
452 return value
453 return value
453
454
454 class AttrLoginValidator(formencode.validators.FancyValidator):
455 class AttrLoginValidator(formencode.validators.FancyValidator):
455
456
456 def to_python(self, value, state):
457 def to_python(self, value, state):
457
458
458 if not value or not isinstance(value, (str, unicode)):
459 if not value or not isinstance(value, (str, unicode)):
459 raise formencode.Invalid(_("The LDAP Login attribute of the CN "
460 raise formencode.Invalid(_("The LDAP Login attribute of the CN "
460 "must be specified - this is the name "
461 "must be specified - this is the name "
461 "of the attribute that is equivalent "
462 "of the attribute that is equivalent "
462 "to 'username'"),
463 "to 'username'"),
463 value, state)
464 value, state)
464
465
465 return value
466 return value
466
467
467 #===============================================================================
468 #===============================================================================
468 # FORMS
469 # FORMS
469 #===============================================================================
470 #===============================================================================
470 class LoginForm(formencode.Schema):
471 class LoginForm(formencode.Schema):
471 allow_extra_fields = True
472 allow_extra_fields = True
472 filter_extra_fields = True
473 filter_extra_fields = True
473 username = UnicodeString(
474 username = UnicodeString(
474 strip=True,
475 strip=True,
475 min=1,
476 min=1,
476 not_empty=True,
477 not_empty=True,
477 messages={
478 messages={
478 'empty':_('Please enter a login'),
479 'empty':_('Please enter a login'),
479 'tooShort':_('Enter a value %(min)i characters long or more')}
480 'tooShort':_('Enter a value %(min)i characters long or more')}
480 )
481 )
481
482
482 password = UnicodeString(
483 password = UnicodeString(
483 strip=True,
484 strip=True,
484 min=3,
485 min=3,
485 not_empty=True,
486 not_empty=True,
486 messages={
487 messages={
487 'empty':_('Please enter a password'),
488 'empty':_('Please enter a password'),
488 'tooShort':_('Enter %(min)i characters or more')}
489 'tooShort':_('Enter %(min)i characters or more')}
489 )
490 )
490
491
491
492
492 #chained validators have access to all data
493 #chained validators have access to all data
493 chained_validators = [ValidAuth]
494 chained_validators = [ValidAuth]
494
495
495 def UserForm(edit=False, old_data={}):
496 def UserForm(edit=False, old_data={}):
496 class _UserForm(formencode.Schema):
497 class _UserForm(formencode.Schema):
497 allow_extra_fields = True
498 allow_extra_fields = True
498 filter_extra_fields = True
499 filter_extra_fields = True
499 username = All(UnicodeString(strip=True, min=1, not_empty=True),
500 username = All(UnicodeString(strip=True, min=1, not_empty=True),
500 ValidUsername(edit, old_data))
501 ValidUsername(edit, old_data))
501 if edit:
502 if edit:
502 new_password = All(UnicodeString(strip=True, min=6, not_empty=False))
503 new_password = All(UnicodeString(strip=True, min=6, not_empty=False))
503 admin = StringBoolean(if_missing=False)
504 admin = StringBoolean(if_missing=False)
504 else:
505 else:
505 password = All(UnicodeString(strip=True, min=6, not_empty=True))
506 password = All(UnicodeString(strip=True, min=6, not_empty=True))
506 active = StringBoolean(if_missing=False)
507 active = StringBoolean(if_missing=False)
507 name = UnicodeString(strip=True, min=1, not_empty=True)
508 name = UnicodeString(strip=True, min=1, not_empty=True)
508 lastname = UnicodeString(strip=True, min=1, not_empty=True)
509 lastname = UnicodeString(strip=True, min=1, not_empty=True)
509 email = All(Email(not_empty=True), UniqSystemEmail(old_data))
510 email = All(Email(not_empty=True), UniqSystemEmail(old_data))
510
511
511 chained_validators = [ValidPassword]
512 chained_validators = [ValidPassword]
512
513
513 return _UserForm
514 return _UserForm
514
515
515
516
516 def UsersGroupForm(edit=False, old_data={}, available_members=[]):
517 def UsersGroupForm(edit=False, old_data={}, available_members=[]):
517 class _UsersGroupForm(formencode.Schema):
518 class _UsersGroupForm(formencode.Schema):
518 allow_extra_fields = True
519 allow_extra_fields = True
519 filter_extra_fields = True
520 filter_extra_fields = True
520
521
521 users_group_name = All(UnicodeString(strip=True, min=1, not_empty=True),
522 users_group_name = All(UnicodeString(strip=True, min=1, not_empty=True),
522 ValidUsersGroup(edit, old_data))
523 ValidUsersGroup(edit, old_data))
523
524
524 users_group_active = StringBoolean(if_missing=False)
525 users_group_active = StringBoolean(if_missing=False)
525
526
526 if edit:
527 if edit:
527 users_group_members = OneOf(available_members, hideList=False,
528 users_group_members = OneOf(available_members, hideList=False,
528 testValueList=True,
529 testValueList=True,
529 if_missing=None, not_empty=False)
530 if_missing=None, not_empty=False)
530
531
531 return _UsersGroupForm
532 return _UsersGroupForm
532
533
533 def ReposGroupForm(edit=False, old_data={}, available_groups=[]):
534 def ReposGroupForm(edit=False, old_data={}, available_groups=[]):
534 class _ReposGroupForm(formencode.Schema):
535 class _ReposGroupForm(formencode.Schema):
535 allow_extra_fields = True
536 allow_extra_fields = True
536 filter_extra_fields = True
537 filter_extra_fields = True
537
538
538 group_name = All(UnicodeString(strip=True, min=1, not_empty=True),
539 group_name = All(UnicodeString(strip=True, min=1, not_empty=True),
539 SlugifyName())
540 SlugifyName())
540 group_description = UnicodeString(strip=True, min=1,
541 group_description = UnicodeString(strip=True, min=1,
541 not_empty=True)
542 not_empty=True)
542 group_parent_id = OneOf(available_groups, hideList=False,
543 group_parent_id = OneOf(available_groups, hideList=False,
543 testValueList=True,
544 testValueList=True,
544 if_missing=None, not_empty=False)
545 if_missing=None, not_empty=False)
545
546
546 chained_validators = [ValidReposGroup(edit, old_data)]
547 chained_validators = [ValidReposGroup(edit, old_data)]
547
548
548 return _ReposGroupForm
549 return _ReposGroupForm
549
550
550 def RegisterForm(edit=False, old_data={}):
551 def RegisterForm(edit=False, old_data={}):
551 class _RegisterForm(formencode.Schema):
552 class _RegisterForm(formencode.Schema):
552 allow_extra_fields = True
553 allow_extra_fields = True
553 filter_extra_fields = True
554 filter_extra_fields = True
554 username = All(ValidUsername(edit, old_data),
555 username = All(ValidUsername(edit, old_data),
555 UnicodeString(strip=True, min=1, not_empty=True))
556 UnicodeString(strip=True, min=1, not_empty=True))
556 password = All(UnicodeString(strip=True, min=6, not_empty=True))
557 password = All(UnicodeString(strip=True, min=6, not_empty=True))
557 password_confirmation = All(UnicodeString(strip=True, min=6, not_empty=True))
558 password_confirmation = All(UnicodeString(strip=True, min=6, not_empty=True))
558 active = StringBoolean(if_missing=False)
559 active = StringBoolean(if_missing=False)
559 name = UnicodeString(strip=True, min=1, not_empty=True)
560 name = UnicodeString(strip=True, min=1, not_empty=True)
560 lastname = UnicodeString(strip=True, min=1, not_empty=True)
561 lastname = UnicodeString(strip=True, min=1, not_empty=True)
561 email = All(Email(not_empty=True), UniqSystemEmail(old_data))
562 email = All(Email(not_empty=True), UniqSystemEmail(old_data))
562
563
563 chained_validators = [ValidPasswordsMatch, ValidPassword]
564 chained_validators = [ValidPasswordsMatch, ValidPassword]
564
565
565 return _RegisterForm
566 return _RegisterForm
566
567
567 def PasswordResetForm():
568 def PasswordResetForm():
568 class _PasswordResetForm(formencode.Schema):
569 class _PasswordResetForm(formencode.Schema):
569 allow_extra_fields = True
570 allow_extra_fields = True
570 filter_extra_fields = True
571 filter_extra_fields = True
571 email = All(ValidSystemEmail(), Email(not_empty=True))
572 email = All(ValidSystemEmail(), Email(not_empty=True))
572 return _PasswordResetForm
573 return _PasswordResetForm
573
574
574 def RepoForm(edit=False, old_data={}, supported_backends=BACKENDS.keys(),
575 def RepoForm(edit=False, old_data={}, supported_backends=BACKENDS.keys(),
575 repo_groups=[]):
576 repo_groups=[]):
576 class _RepoForm(formencode.Schema):
577 class _RepoForm(formencode.Schema):
577 allow_extra_fields = True
578 allow_extra_fields = True
578 filter_extra_fields = False
579 filter_extra_fields = False
579 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True),
580 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True),
580 SlugifyName())
581 SlugifyName())
581 clone_uri = All(UnicodeString(strip=True, min=1, not_empty=False),
582 clone_uri = All(UnicodeString(strip=True, min=1, not_empty=False),
582 ValidCloneUri()())
583 ValidCloneUri()())
583 repo_group = OneOf(repo_groups, hideList=True)
584 repo_group = OneOf(repo_groups, hideList=True)
584 repo_type = OneOf(supported_backends)
585 repo_type = OneOf(supported_backends)
585 description = UnicodeString(strip=True, min=1, not_empty=True)
586 description = UnicodeString(strip=True, min=1, not_empty=True)
586 private = StringBoolean(if_missing=False)
587 private = StringBoolean(if_missing=False)
587 enable_statistics = StringBoolean(if_missing=False)
588 enable_statistics = StringBoolean(if_missing=False)
588 enable_downloads = StringBoolean(if_missing=False)
589 enable_downloads = StringBoolean(if_missing=False)
589
590
590 if edit:
591 if edit:
591 #this is repo owner
592 #this is repo owner
592 user = All(UnicodeString(not_empty=True), ValidRepoUser)
593 user = All(UnicodeString(not_empty=True), ValidRepoUser)
593
594
594 chained_validators = [ValidRepoName(edit, old_data), ValidPerms]
595 chained_validators = [ValidRepoName(edit, old_data), ValidPerms]
595 return _RepoForm
596 return _RepoForm
596
597
597 def RepoForkForm(edit=False, old_data={}, supported_backends=BACKENDS.keys()):
598 def RepoForkForm(edit=False, old_data={}, supported_backends=BACKENDS.keys()):
598 class _RepoForkForm(formencode.Schema):
599 class _RepoForkForm(formencode.Schema):
599 allow_extra_fields = True
600 allow_extra_fields = True
600 filter_extra_fields = False
601 filter_extra_fields = False
601 fork_name = All(UnicodeString(strip=True, min=1, not_empty=True),
602 fork_name = All(UnicodeString(strip=True, min=1, not_empty=True),
602 SlugifyName())
603 SlugifyName())
603 description = UnicodeString(strip=True, min=1, not_empty=True)
604 description = UnicodeString(strip=True, min=1, not_empty=True)
604 private = StringBoolean(if_missing=False)
605 private = StringBoolean(if_missing=False)
605 repo_type = All(ValidForkType(old_data), OneOf(supported_backends))
606 repo_type = All(ValidForkType(old_data), OneOf(supported_backends))
606
607
607 chained_validators = [ValidForkName()]
608 chained_validators = [ValidForkName()]
608
609
609 return _RepoForkForm
610 return _RepoForkForm
610
611
611 def RepoSettingsForm(edit=False, old_data={}):
612 def RepoSettingsForm(edit=False, old_data={}):
612 class _RepoForm(formencode.Schema):
613 class _RepoForm(formencode.Schema):
613 allow_extra_fields = True
614 allow_extra_fields = True
614 filter_extra_fields = False
615 filter_extra_fields = False
615 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True),
616 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True),
616 SlugifyName())
617 SlugifyName())
617 description = UnicodeString(strip=True, min=1, not_empty=True)
618 description = UnicodeString(strip=True, min=1, not_empty=True)
618 private = StringBoolean(if_missing=False)
619 private = StringBoolean(if_missing=False)
619
620
620 chained_validators = [ValidRepoName(edit, old_data), ValidPerms, ValidSettings]
621 chained_validators = [ValidRepoName(edit, old_data), ValidPerms, ValidSettings]
621 return _RepoForm
622 return _RepoForm
622
623
623
624
624 def ApplicationSettingsForm():
625 def ApplicationSettingsForm():
625 class _ApplicationSettingsForm(formencode.Schema):
626 class _ApplicationSettingsForm(formencode.Schema):
626 allow_extra_fields = True
627 allow_extra_fields = True
627 filter_extra_fields = False
628 filter_extra_fields = False
628 rhodecode_title = UnicodeString(strip=True, min=1, not_empty=True)
629 rhodecode_title = UnicodeString(strip=True, min=1, not_empty=True)
629 rhodecode_realm = UnicodeString(strip=True, min=1, not_empty=True)
630 rhodecode_realm = UnicodeString(strip=True, min=1, not_empty=True)
630 rhodecode_ga_code = UnicodeString(strip=True, min=1, not_empty=False)
631 rhodecode_ga_code = UnicodeString(strip=True, min=1, not_empty=False)
631
632
632 return _ApplicationSettingsForm
633 return _ApplicationSettingsForm
633
634
634 def ApplicationUiSettingsForm():
635 def ApplicationUiSettingsForm():
635 class _ApplicationUiSettingsForm(formencode.Schema):
636 class _ApplicationUiSettingsForm(formencode.Schema):
636 allow_extra_fields = True
637 allow_extra_fields = True
637 filter_extra_fields = False
638 filter_extra_fields = False
638 web_push_ssl = OneOf(['true', 'false'], if_missing='false')
639 web_push_ssl = OneOf(['true', 'false'], if_missing='false')
639 paths_root_path = All(ValidPath(), UnicodeString(strip=True, min=1, not_empty=True))
640 paths_root_path = All(ValidPath(), UnicodeString(strip=True, min=1, not_empty=True))
640 hooks_changegroup_update = OneOf(['True', 'False'], if_missing=False)
641 hooks_changegroup_update = OneOf(['True', 'False'], if_missing=False)
641 hooks_changegroup_repo_size = OneOf(['True', 'False'], if_missing=False)
642 hooks_changegroup_repo_size = OneOf(['True', 'False'], if_missing=False)
642 hooks_pretxnchangegroup_push_logger = OneOf(['True', 'False'], if_missing=False)
643 hooks_pretxnchangegroup_push_logger = OneOf(['True', 'False'], if_missing=False)
643 hooks_preoutgoing_pull_logger = OneOf(['True', 'False'], if_missing=False)
644 hooks_preoutgoing_pull_logger = OneOf(['True', 'False'], if_missing=False)
644
645
645 return _ApplicationUiSettingsForm
646 return _ApplicationUiSettingsForm
646
647
647 def DefaultPermissionsForm(perms_choices, register_choices, create_choices):
648 def DefaultPermissionsForm(perms_choices, register_choices, create_choices):
648 class _DefaultPermissionsForm(formencode.Schema):
649 class _DefaultPermissionsForm(formencode.Schema):
649 allow_extra_fields = True
650 allow_extra_fields = True
650 filter_extra_fields = True
651 filter_extra_fields = True
651 overwrite_default = StringBoolean(if_missing=False)
652 overwrite_default = StringBoolean(if_missing=False)
652 anonymous = OneOf(['True', 'False'], if_missing=False)
653 anonymous = OneOf(['True', 'False'], if_missing=False)
653 default_perm = OneOf(perms_choices)
654 default_perm = OneOf(perms_choices)
654 default_register = OneOf(register_choices)
655 default_register = OneOf(register_choices)
655 default_create = OneOf(create_choices)
656 default_create = OneOf(create_choices)
656
657
657 return _DefaultPermissionsForm
658 return _DefaultPermissionsForm
658
659
659
660
660 def LdapSettingsForm(tls_reqcert_choices, search_scope_choices, tls_kind_choices):
661 def LdapSettingsForm(tls_reqcert_choices, search_scope_choices, tls_kind_choices):
661 class _LdapSettingsForm(formencode.Schema):
662 class _LdapSettingsForm(formencode.Schema):
662 allow_extra_fields = True
663 allow_extra_fields = True
663 filter_extra_fields = True
664 filter_extra_fields = True
664 pre_validators = [LdapLibValidator]
665 pre_validators = [LdapLibValidator]
665 ldap_active = StringBoolean(if_missing=False)
666 ldap_active = StringBoolean(if_missing=False)
666 ldap_host = UnicodeString(strip=True,)
667 ldap_host = UnicodeString(strip=True,)
667 ldap_port = Number(strip=True,)
668 ldap_port = Number(strip=True,)
668 ldap_tls_kind = OneOf(tls_kind_choices)
669 ldap_tls_kind = OneOf(tls_kind_choices)
669 ldap_tls_reqcert = OneOf(tls_reqcert_choices)
670 ldap_tls_reqcert = OneOf(tls_reqcert_choices)
670 ldap_dn_user = UnicodeString(strip=True,)
671 ldap_dn_user = UnicodeString(strip=True,)
671 ldap_dn_pass = UnicodeString(strip=True,)
672 ldap_dn_pass = UnicodeString(strip=True,)
672 ldap_base_dn = UnicodeString(strip=True,)
673 ldap_base_dn = UnicodeString(strip=True,)
673 ldap_filter = UnicodeString(strip=True,)
674 ldap_filter = UnicodeString(strip=True,)
674 ldap_search_scope = OneOf(search_scope_choices)
675 ldap_search_scope = OneOf(search_scope_choices)
675 ldap_attr_login = All(AttrLoginValidator, UnicodeString(strip=True,))
676 ldap_attr_login = All(AttrLoginValidator, UnicodeString(strip=True,))
676 ldap_attr_firstname = UnicodeString(strip=True,)
677 ldap_attr_firstname = UnicodeString(strip=True,)
677 ldap_attr_lastname = UnicodeString(strip=True,)
678 ldap_attr_lastname = UnicodeString(strip=True,)
678 ldap_attr_email = UnicodeString(strip=True,)
679 ldap_attr_email = UnicodeString(strip=True,)
679
680
680 return _LdapSettingsForm
681 return _LdapSettingsForm
General Comments 0
You need to be logged in to leave comments. Login now