##// END OF EJS Templates
remove ipdb trace
marcink -
r3223:74e455c0 beta
parent child Browse files
Show More
@@ -1,793 +1,786 b''
1 """
1 """
2 Set of generic validators
2 Set of generic validators
3 """
3 """
4 import os
4 import os
5 import re
5 import re
6 import formencode
6 import formencode
7 import logging
7 import logging
8 from collections import defaultdict
8 from collections import defaultdict
9 from pylons.i18n.translation import _
9 from pylons.i18n.translation import _
10 from webhelpers.pylonslib.secure_form import authentication_token
10 from webhelpers.pylonslib.secure_form import authentication_token
11
11
12 from formencode.validators import (
12 from formencode.validators import (
13 UnicodeString, OneOf, Int, Number, Regex, Email, Bool, StringBoolean, Set,
13 UnicodeString, OneOf, Int, Number, Regex, Email, Bool, StringBoolean, Set,
14 NotEmpty, IPAddress, CIDR
14 NotEmpty, IPAddress, CIDR
15 )
15 )
16 from rhodecode.lib.compat import OrderedSet
16 from rhodecode.lib.compat import OrderedSet
17 from rhodecode.lib import ipaddr
17 from rhodecode.lib import ipaddr
18 from rhodecode.lib.utils import repo_name_slug
18 from rhodecode.lib.utils import repo_name_slug
19 from rhodecode.model.db import RepoGroup, Repository, UsersGroup, User,\
19 from rhodecode.model.db import RepoGroup, Repository, UsersGroup, User,\
20 ChangesetStatus
20 ChangesetStatus
21 from rhodecode.lib.exceptions import LdapImportError
21 from rhodecode.lib.exceptions import LdapImportError
22 from rhodecode.config.routing import ADMIN_PREFIX
22 from rhodecode.config.routing import ADMIN_PREFIX
23 from rhodecode.lib.auth import HasReposGroupPermissionAny
23 from rhodecode.lib.auth import HasReposGroupPermissionAny
24
24
25 # silence warnings and pylint
25 # silence warnings and pylint
26 UnicodeString, OneOf, Int, Number, Regex, Email, Bool, StringBoolean, Set, \
26 UnicodeString, OneOf, Int, Number, Regex, Email, Bool, StringBoolean, Set, \
27 NotEmpty, IPAddress, CIDR
27 NotEmpty, IPAddress, CIDR
28
28
29 log = logging.getLogger(__name__)
29 log = logging.getLogger(__name__)
30
30
31
31
32 class UniqueList(formencode.FancyValidator):
32 class UniqueList(formencode.FancyValidator):
33 """
33 """
34 Unique List !
34 Unique List !
35 """
35 """
36 messages = dict(
36 messages = dict(
37 empty=_('Value cannot be an empty list'),
37 empty=_('Value cannot be an empty list'),
38 missing_value=_('Value cannot be an empty list'),
38 missing_value=_('Value cannot be an empty list'),
39 )
39 )
40
40
41 def _to_python(self, value, state):
41 def _to_python(self, value, state):
42 if isinstance(value, list):
42 if isinstance(value, list):
43 return value
43 return value
44 elif isinstance(value, set):
44 elif isinstance(value, set):
45 return list(value)
45 return list(value)
46 elif isinstance(value, tuple):
46 elif isinstance(value, tuple):
47 return list(value)
47 return list(value)
48 elif value is None:
48 elif value is None:
49 return []
49 return []
50 else:
50 else:
51 return [value]
51 return [value]
52
52
53 def empty_value(self, value):
53 def empty_value(self, value):
54 return []
54 return []
55
55
56
56
57 class StateObj(object):
57 class StateObj(object):
58 """
58 """
59 this is needed to translate the messages using _() in validators
59 this is needed to translate the messages using _() in validators
60 """
60 """
61 _ = staticmethod(_)
61 _ = staticmethod(_)
62
62
63
63
64 def M(self, key, state=None, **kwargs):
64 def M(self, key, state=None, **kwargs):
65 """
65 """
66 returns string from self.message based on given key,
66 returns string from self.message based on given key,
67 passed kw params are used to substitute %(named)s params inside
67 passed kw params are used to substitute %(named)s params inside
68 translated strings
68 translated strings
69
69
70 :param msg:
70 :param msg:
71 :param state:
71 :param state:
72 """
72 """
73 if state is None:
73 if state is None:
74 state = StateObj()
74 state = StateObj()
75 else:
75 else:
76 state._ = staticmethod(_)
76 state._ = staticmethod(_)
77 #inject validator into state object
77 #inject validator into state object
78 return self.message(key, state, **kwargs)
78 return self.message(key, state, **kwargs)
79
79
80
80
81 def ValidUsername(edit=False, old_data={}):
81 def ValidUsername(edit=False, old_data={}):
82 class _validator(formencode.validators.FancyValidator):
82 class _validator(formencode.validators.FancyValidator):
83 messages = {
83 messages = {
84 'username_exists': _(u'Username "%(username)s" already exists'),
84 'username_exists': _(u'Username "%(username)s" already exists'),
85 'system_invalid_username':
85 'system_invalid_username':
86 _(u'Username "%(username)s" is forbidden'),
86 _(u'Username "%(username)s" is forbidden'),
87 'invalid_username':
87 'invalid_username':
88 _(u'Username may only contain alphanumeric characters '
88 _(u'Username may only contain alphanumeric characters '
89 'underscores, periods or dashes and must begin with '
89 'underscores, periods or dashes and must begin with '
90 'alphanumeric character')
90 'alphanumeric character')
91 }
91 }
92
92
93 def validate_python(self, value, state):
93 def validate_python(self, value, state):
94 if value in ['default', 'new_user']:
94 if value in ['default', 'new_user']:
95 msg = M(self, 'system_invalid_username', state, username=value)
95 msg = M(self, 'system_invalid_username', state, username=value)
96 raise formencode.Invalid(msg, value, state)
96 raise formencode.Invalid(msg, value, state)
97 #check if user is unique
97 #check if user is unique
98 old_un = None
98 old_un = None
99 if edit:
99 if edit:
100 old_un = User.get(old_data.get('user_id')).username
100 old_un = User.get(old_data.get('user_id')).username
101
101
102 if old_un != value or not edit:
102 if old_un != value or not edit:
103 if User.get_by_username(value, case_insensitive=True):
103 if User.get_by_username(value, case_insensitive=True):
104 msg = M(self, 'username_exists', state, username=value)
104 msg = M(self, 'username_exists', state, username=value)
105 raise formencode.Invalid(msg, value, state)
105 raise formencode.Invalid(msg, value, state)
106
106
107 if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]*$', value) is None:
107 if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]*$', value) is None:
108 msg = M(self, 'invalid_username', state)
108 msg = M(self, 'invalid_username', state)
109 raise formencode.Invalid(msg, value, state)
109 raise formencode.Invalid(msg, value, state)
110 return _validator
110 return _validator
111
111
112
112
113 def ValidRepoUser():
113 def ValidRepoUser():
114 class _validator(formencode.validators.FancyValidator):
114 class _validator(formencode.validators.FancyValidator):
115 messages = {
115 messages = {
116 'invalid_username': _(u'Username %(username)s is not valid')
116 'invalid_username': _(u'Username %(username)s is not valid')
117 }
117 }
118
118
119 def validate_python(self, value, state):
119 def validate_python(self, value, state):
120 try:
120 try:
121 User.query().filter(User.active == True)\
121 User.query().filter(User.active == True)\
122 .filter(User.username == value).one()
122 .filter(User.username == value).one()
123 except Exception:
123 except Exception:
124 msg = M(self, 'invalid_username', state, username=value)
124 msg = M(self, 'invalid_username', state, username=value)
125 raise formencode.Invalid(msg, value, state,
125 raise formencode.Invalid(msg, value, state,
126 error_dict=dict(username=msg)
126 error_dict=dict(username=msg)
127 )
127 )
128
128
129 return _validator
129 return _validator
130
130
131
131
132 def ValidUsersGroup(edit=False, old_data={}):
132 def ValidUsersGroup(edit=False, old_data={}):
133 class _validator(formencode.validators.FancyValidator):
133 class _validator(formencode.validators.FancyValidator):
134 messages = {
134 messages = {
135 'invalid_group': _(u'Invalid users group name'),
135 'invalid_group': _(u'Invalid users group name'),
136 'group_exist': _(u'Users group "%(usersgroup)s" already exists'),
136 'group_exist': _(u'Users group "%(usersgroup)s" already exists'),
137 'invalid_usersgroup_name':
137 'invalid_usersgroup_name':
138 _(u'users group name may only contain alphanumeric '
138 _(u'users group name may only contain alphanumeric '
139 'characters underscores, periods or dashes and must begin '
139 'characters underscores, periods or dashes and must begin '
140 'with alphanumeric character')
140 'with alphanumeric character')
141 }
141 }
142
142
143 def validate_python(self, value, state):
143 def validate_python(self, value, state):
144 if value in ['default']:
144 if value in ['default']:
145 msg = M(self, 'invalid_group', state)
145 msg = M(self, 'invalid_group', state)
146 raise formencode.Invalid(msg, value, state,
146 raise formencode.Invalid(msg, value, state,
147 error_dict=dict(users_group_name=msg)
147 error_dict=dict(users_group_name=msg)
148 )
148 )
149 #check if group is unique
149 #check if group is unique
150 old_ugname = None
150 old_ugname = None
151 if edit:
151 if edit:
152 old_id = old_data.get('users_group_id')
152 old_id = old_data.get('users_group_id')
153 old_ugname = UsersGroup.get(old_id).users_group_name
153 old_ugname = UsersGroup.get(old_id).users_group_name
154
154
155 if old_ugname != value or not edit:
155 if old_ugname != value or not edit:
156 is_existing_group = UsersGroup.get_by_group_name(value,
156 is_existing_group = UsersGroup.get_by_group_name(value,
157 case_insensitive=True)
157 case_insensitive=True)
158 if is_existing_group:
158 if is_existing_group:
159 msg = M(self, 'group_exist', state, usersgroup=value)
159 msg = M(self, 'group_exist', state, usersgroup=value)
160 raise formencode.Invalid(msg, value, state,
160 raise formencode.Invalid(msg, value, state,
161 error_dict=dict(users_group_name=msg)
161 error_dict=dict(users_group_name=msg)
162 )
162 )
163
163
164 if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None:
164 if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None:
165 msg = M(self, 'invalid_usersgroup_name', state)
165 msg = M(self, 'invalid_usersgroup_name', state)
166 raise formencode.Invalid(msg, value, state,
166 raise formencode.Invalid(msg, value, state,
167 error_dict=dict(users_group_name=msg)
167 error_dict=dict(users_group_name=msg)
168 )
168 )
169
169
170 return _validator
170 return _validator
171
171
172
172
173 def ValidReposGroup(edit=False, old_data={}):
173 def ValidReposGroup(edit=False, old_data={}):
174 class _validator(formencode.validators.FancyValidator):
174 class _validator(formencode.validators.FancyValidator):
175 messages = {
175 messages = {
176 'group_parent_id': _(u'Cannot assign this group as parent'),
176 'group_parent_id': _(u'Cannot assign this group as parent'),
177 'group_exists': _(u'Group "%(group_name)s" already exists'),
177 'group_exists': _(u'Group "%(group_name)s" already exists'),
178 'repo_exists':
178 'repo_exists':
179 _(u'Repository with name "%(group_name)s" already exists')
179 _(u'Repository with name "%(group_name)s" already exists')
180 }
180 }
181
181
182 def validate_python(self, value, state):
182 def validate_python(self, value, state):
183 # TODO WRITE VALIDATIONS
183 # TODO WRITE VALIDATIONS
184 group_name = value.get('group_name')
184 group_name = value.get('group_name')
185 group_parent_id = value.get('group_parent_id')
185 group_parent_id = value.get('group_parent_id')
186
186
187 # slugify repo group just in case :)
187 # slugify repo group just in case :)
188 slug = repo_name_slug(group_name)
188 slug = repo_name_slug(group_name)
189
189
190 # check for parent of self
190 # check for parent of self
191 parent_of_self = lambda: (
191 parent_of_self = lambda: (
192 old_data['group_id'] == int(group_parent_id)
192 old_data['group_id'] == int(group_parent_id)
193 if group_parent_id else False
193 if group_parent_id else False
194 )
194 )
195 if edit and parent_of_self():
195 if edit and parent_of_self():
196 msg = M(self, 'group_parent_id', state)
196 msg = M(self, 'group_parent_id', state)
197 raise formencode.Invalid(msg, value, state,
197 raise formencode.Invalid(msg, value, state,
198 error_dict=dict(group_parent_id=msg)
198 error_dict=dict(group_parent_id=msg)
199 )
199 )
200
200
201 old_gname = None
201 old_gname = None
202 if edit:
202 if edit:
203 old_gname = RepoGroup.get(old_data.get('group_id')).group_name
203 old_gname = RepoGroup.get(old_data.get('group_id')).group_name
204
204
205 if old_gname != group_name or not edit:
205 if old_gname != group_name or not edit:
206
206
207 # check group
207 # check group
208 gr = RepoGroup.query()\
208 gr = RepoGroup.query()\
209 .filter(RepoGroup.group_name == slug)\
209 .filter(RepoGroup.group_name == slug)\
210 .filter(RepoGroup.group_parent_id == group_parent_id)\
210 .filter(RepoGroup.group_parent_id == group_parent_id)\
211 .scalar()
211 .scalar()
212
212
213 if gr:
213 if gr:
214 msg = M(self, 'group_exists', state, group_name=slug)
214 msg = M(self, 'group_exists', state, group_name=slug)
215 raise formencode.Invalid(msg, value, state,
215 raise formencode.Invalid(msg, value, state,
216 error_dict=dict(group_name=msg)
216 error_dict=dict(group_name=msg)
217 )
217 )
218
218
219 # check for same repo
219 # check for same repo
220 repo = Repository.query()\
220 repo = Repository.query()\
221 .filter(Repository.repo_name == slug)\
221 .filter(Repository.repo_name == slug)\
222 .scalar()
222 .scalar()
223
223
224 if repo:
224 if repo:
225 msg = M(self, 'repo_exists', state, group_name=slug)
225 msg = M(self, 'repo_exists', state, group_name=slug)
226 raise formencode.Invalid(msg, value, state,
226 raise formencode.Invalid(msg, value, state,
227 error_dict=dict(group_name=msg)
227 error_dict=dict(group_name=msg)
228 )
228 )
229
229
230 return _validator
230 return _validator
231
231
232
232
233 def ValidPassword():
233 def ValidPassword():
234 class _validator(formencode.validators.FancyValidator):
234 class _validator(formencode.validators.FancyValidator):
235 messages = {
235 messages = {
236 'invalid_password':
236 'invalid_password':
237 _(u'Invalid characters (non-ascii) in password')
237 _(u'Invalid characters (non-ascii) in password')
238 }
238 }
239
239
240 def validate_python(self, value, state):
240 def validate_python(self, value, state):
241 try:
241 try:
242 (value or '').decode('ascii')
242 (value or '').decode('ascii')
243 except UnicodeError:
243 except UnicodeError:
244 msg = M(self, 'invalid_password', state)
244 msg = M(self, 'invalid_password', state)
245 raise formencode.Invalid(msg, value, state,)
245 raise formencode.Invalid(msg, value, state,)
246 return _validator
246 return _validator
247
247
248
248
249 def ValidPasswordsMatch():
249 def ValidPasswordsMatch():
250 class _validator(formencode.validators.FancyValidator):
250 class _validator(formencode.validators.FancyValidator):
251 messages = {
251 messages = {
252 'password_mismatch': _(u'Passwords do not match'),
252 'password_mismatch': _(u'Passwords do not match'),
253 }
253 }
254
254
255 def validate_python(self, value, state):
255 def validate_python(self, value, state):
256
256
257 pass_val = value.get('password') or value.get('new_password')
257 pass_val = value.get('password') or value.get('new_password')
258 if pass_val != value['password_confirmation']:
258 if pass_val != value['password_confirmation']:
259 msg = M(self, 'password_mismatch', state)
259 msg = M(self, 'password_mismatch', state)
260 raise formencode.Invalid(msg, value, state,
260 raise formencode.Invalid(msg, value, state,
261 error_dict=dict(password_confirmation=msg)
261 error_dict=dict(password_confirmation=msg)
262 )
262 )
263 return _validator
263 return _validator
264
264
265
265
266 def ValidAuth():
266 def ValidAuth():
267 class _validator(formencode.validators.FancyValidator):
267 class _validator(formencode.validators.FancyValidator):
268 messages = {
268 messages = {
269 'invalid_password': _(u'invalid password'),
269 'invalid_password': _(u'invalid password'),
270 'invalid_username': _(u'invalid user name'),
270 'invalid_username': _(u'invalid user name'),
271 'disabled_account': _(u'Your account is disabled')
271 'disabled_account': _(u'Your account is disabled')
272 }
272 }
273
273
274 def validate_python(self, value, state):
274 def validate_python(self, value, state):
275 from rhodecode.lib.auth import authenticate
275 from rhodecode.lib.auth import authenticate
276
276
277 password = value['password']
277 password = value['password']
278 username = value['username']
278 username = value['username']
279
279
280 if not authenticate(username, password):
280 if not authenticate(username, password):
281 user = User.get_by_username(username)
281 user = User.get_by_username(username)
282 if user and user.active is False:
282 if user and user.active is False:
283 log.warning('user %s is disabled' % username)
283 log.warning('user %s is disabled' % username)
284 msg = M(self, 'disabled_account', state)
284 msg = M(self, 'disabled_account', state)
285 raise formencode.Invalid(msg, value, state,
285 raise formencode.Invalid(msg, value, state,
286 error_dict=dict(username=msg)
286 error_dict=dict(username=msg)
287 )
287 )
288 else:
288 else:
289 log.warning('user %s failed to authenticate' % username)
289 log.warning('user %s failed to authenticate' % username)
290 msg = M(self, 'invalid_username', state)
290 msg = M(self, 'invalid_username', state)
291 msg2 = M(self, 'invalid_password', state)
291 msg2 = M(self, 'invalid_password', state)
292 raise formencode.Invalid(msg, value, state,
292 raise formencode.Invalid(msg, value, state,
293 error_dict=dict(username=msg, password=msg2)
293 error_dict=dict(username=msg, password=msg2)
294 )
294 )
295 return _validator
295 return _validator
296
296
297
297
298 def ValidAuthToken():
298 def ValidAuthToken():
299 class _validator(formencode.validators.FancyValidator):
299 class _validator(formencode.validators.FancyValidator):
300 messages = {
300 messages = {
301 'invalid_token': _(u'Token mismatch')
301 'invalid_token': _(u'Token mismatch')
302 }
302 }
303
303
304 def validate_python(self, value, state):
304 def validate_python(self, value, state):
305 if value != authentication_token():
305 if value != authentication_token():
306 msg = M(self, 'invalid_token', state)
306 msg = M(self, 'invalid_token', state)
307 raise formencode.Invalid(msg, value, state)
307 raise formencode.Invalid(msg, value, state)
308 return _validator
308 return _validator
309
309
310
310
311 def ValidRepoName(edit=False, old_data={}):
311 def ValidRepoName(edit=False, old_data={}):
312 class _validator(formencode.validators.FancyValidator):
312 class _validator(formencode.validators.FancyValidator):
313 messages = {
313 messages = {
314 'invalid_repo_name':
314 'invalid_repo_name':
315 _(u'Repository name %(repo)s is disallowed'),
315 _(u'Repository name %(repo)s is disallowed'),
316 'repository_exists':
316 'repository_exists':
317 _(u'Repository named %(repo)s already exists'),
317 _(u'Repository named %(repo)s already exists'),
318 'repository_in_group_exists': _(u'Repository "%(repo)s" already '
318 'repository_in_group_exists': _(u'Repository "%(repo)s" already '
319 'exists in group "%(group)s"'),
319 'exists in group "%(group)s"'),
320 'same_group_exists': _(u'Repositories group with name "%(repo)s" '
320 'same_group_exists': _(u'Repositories group with name "%(repo)s" '
321 'already exists')
321 'already exists')
322 }
322 }
323
323
324 def _to_python(self, value, state):
324 def _to_python(self, value, state):
325 repo_name = repo_name_slug(value.get('repo_name', ''))
325 repo_name = repo_name_slug(value.get('repo_name', ''))
326 repo_group = value.get('repo_group')
326 repo_group = value.get('repo_group')
327 if repo_group:
327 if repo_group:
328 gr = RepoGroup.get(repo_group)
328 gr = RepoGroup.get(repo_group)
329 group_path = gr.full_path
329 group_path = gr.full_path
330 group_name = gr.group_name
330 group_name = gr.group_name
331 # value needs to be aware of group name in order to check
331 # value needs to be aware of group name in order to check
332 # db key This is an actual just the name to store in the
332 # db key This is an actual just the name to store in the
333 # database
333 # database
334 repo_name_full = group_path + RepoGroup.url_sep() + repo_name
334 repo_name_full = group_path + RepoGroup.url_sep() + repo_name
335 else:
335 else:
336 group_name = group_path = ''
336 group_name = group_path = ''
337 repo_name_full = repo_name
337 repo_name_full = repo_name
338
338
339 value['repo_name'] = repo_name
339 value['repo_name'] = repo_name
340 value['repo_name_full'] = repo_name_full
340 value['repo_name_full'] = repo_name_full
341 value['group_path'] = group_path
341 value['group_path'] = group_path
342 value['group_name'] = group_name
342 value['group_name'] = group_name
343 return value
343 return value
344
344
345 def validate_python(self, value, state):
345 def validate_python(self, value, state):
346
346
347 repo_name = value.get('repo_name')
347 repo_name = value.get('repo_name')
348 repo_name_full = value.get('repo_name_full')
348 repo_name_full = value.get('repo_name_full')
349 group_path = value.get('group_path')
349 group_path = value.get('group_path')
350 group_name = value.get('group_name')
350 group_name = value.get('group_name')
351
351
352 if repo_name in [ADMIN_PREFIX, '']:
352 if repo_name in [ADMIN_PREFIX, '']:
353 msg = M(self, 'invalid_repo_name', state, repo=repo_name)
353 msg = M(self, 'invalid_repo_name', state, repo=repo_name)
354 raise formencode.Invalid(msg, value, state,
354 raise formencode.Invalid(msg, value, state,
355 error_dict=dict(repo_name=msg)
355 error_dict=dict(repo_name=msg)
356 )
356 )
357
357
358 rename = old_data.get('repo_name') != repo_name_full
358 rename = old_data.get('repo_name') != repo_name_full
359 create = not edit
359 create = not edit
360 if rename or create:
360 if rename or create:
361
361
362 if group_path != '':
362 if group_path != '':
363 if Repository.get_by_repo_name(repo_name_full):
363 if Repository.get_by_repo_name(repo_name_full):
364 msg = M(self, 'repository_in_group_exists', state,
364 msg = M(self, 'repository_in_group_exists', state,
365 repo=repo_name, group=group_name)
365 repo=repo_name, group=group_name)
366 raise formencode.Invalid(msg, value, state,
366 raise formencode.Invalid(msg, value, state,
367 error_dict=dict(repo_name=msg)
367 error_dict=dict(repo_name=msg)
368 )
368 )
369 elif RepoGroup.get_by_group_name(repo_name_full):
369 elif RepoGroup.get_by_group_name(repo_name_full):
370 msg = M(self, 'same_group_exists', state,
370 msg = M(self, 'same_group_exists', state,
371 repo=repo_name)
371 repo=repo_name)
372 raise formencode.Invalid(msg, value, state,
372 raise formencode.Invalid(msg, value, state,
373 error_dict=dict(repo_name=msg)
373 error_dict=dict(repo_name=msg)
374 )
374 )
375
375
376 elif Repository.get_by_repo_name(repo_name_full):
376 elif Repository.get_by_repo_name(repo_name_full):
377 msg = M(self, 'repository_exists', state,
377 msg = M(self, 'repository_exists', state,
378 repo=repo_name)
378 repo=repo_name)
379 raise formencode.Invalid(msg, value, state,
379 raise formencode.Invalid(msg, value, state,
380 error_dict=dict(repo_name=msg)
380 error_dict=dict(repo_name=msg)
381 )
381 )
382 return value
382 return value
383 return _validator
383 return _validator
384
384
385
385
386 def ValidForkName(*args, **kwargs):
386 def ValidForkName(*args, **kwargs):
387 return ValidRepoName(*args, **kwargs)
387 return ValidRepoName(*args, **kwargs)
388
388
389
389
390 def SlugifyName():
390 def SlugifyName():
391 class _validator(formencode.validators.FancyValidator):
391 class _validator(formencode.validators.FancyValidator):
392
392
393 def _to_python(self, value, state):
393 def _to_python(self, value, state):
394 return repo_name_slug(value)
394 return repo_name_slug(value)
395
395
396 def validate_python(self, value, state):
396 def validate_python(self, value, state):
397 pass
397 pass
398
398
399 return _validator
399 return _validator
400
400
401
401
402 def ValidCloneUri():
402 def ValidCloneUri():
403 from rhodecode.lib.utils import make_ui
403 from rhodecode.lib.utils import make_ui
404
404
405 def url_handler(repo_type, url, ui=None):
405 def url_handler(repo_type, url, ui=None):
406 if repo_type == 'hg':
406 if repo_type == 'hg':
407 from rhodecode.lib.vcs.backends.hg.repository import MercurialRepository
407 from rhodecode.lib.vcs.backends.hg.repository import MercurialRepository
408 from mercurial.httppeer import httppeer
408 from mercurial.httppeer import httppeer
409 if url.startswith('http'):
409 if url.startswith('http'):
410 ## initially check if it's at least the proper URL
410 ## initially check if it's at least the proper URL
411 ## or does it pass basic auth
411 ## or does it pass basic auth
412 MercurialRepository._check_url(url)
412 MercurialRepository._check_url(url)
413 httppeer(ui, url)._capabilities()
413 httppeer(ui, url)._capabilities()
414 elif url.startswith('svn+http'):
414 elif url.startswith('svn+http'):
415 from hgsubversion.svnrepo import svnremoterepo
415 from hgsubversion.svnrepo import svnremoterepo
416 svnremoterepo(ui, url).capabilities
416 svnremoterepo(ui, url).capabilities
417 elif url.startswith('git+http'):
417 elif url.startswith('git+http'):
418 raise NotImplementedError()
418 raise NotImplementedError()
419
419
420 elif repo_type == 'git':
420 elif repo_type == 'git':
421 from rhodecode.lib.vcs.backends.git.repository import GitRepository
421 from rhodecode.lib.vcs.backends.git.repository import GitRepository
422 if url.startswith('http'):
422 if url.startswith('http'):
423 ## initially check if it's at least the proper URL
423 ## initially check if it's at least the proper URL
424 ## or does it pass basic auth
424 ## or does it pass basic auth
425 GitRepository._check_url(url)
425 GitRepository._check_url(url)
426 elif url.startswith('svn+http'):
426 elif url.startswith('svn+http'):
427 raise NotImplementedError()
427 raise NotImplementedError()
428 elif url.startswith('hg+http'):
428 elif url.startswith('hg+http'):
429 raise NotImplementedError()
429 raise NotImplementedError()
430
430
431 class _validator(formencode.validators.FancyValidator):
431 class _validator(formencode.validators.FancyValidator):
432 messages = {
432 messages = {
433 'clone_uri': _(u'invalid clone url'),
433 'clone_uri': _(u'invalid clone url'),
434 'invalid_clone_uri': _(u'Invalid clone url, provide a '
434 'invalid_clone_uri': _(u'Invalid clone url, provide a '
435 'valid clone http(s)/svn+http(s) url')
435 'valid clone http(s)/svn+http(s) url')
436 }
436 }
437
437
438 def validate_python(self, value, state):
438 def validate_python(self, value, state):
439 repo_type = value.get('repo_type')
439 repo_type = value.get('repo_type')
440 url = value.get('clone_uri')
440 url = value.get('clone_uri')
441
441
442 if not url:
442 if not url:
443 pass
443 pass
444 else:
444 else:
445 try:
445 try:
446 url_handler(repo_type, url, make_ui('db', clear_session=False))
446 url_handler(repo_type, url, make_ui('db', clear_session=False))
447 except Exception:
447 except Exception:
448 log.exception('Url validation failed')
448 log.exception('Url validation failed')
449 msg = M(self, 'clone_uri')
449 msg = M(self, 'clone_uri')
450 raise formencode.Invalid(msg, value, state,
450 raise formencode.Invalid(msg, value, state,
451 error_dict=dict(clone_uri=msg)
451 error_dict=dict(clone_uri=msg)
452 )
452 )
453 return _validator
453 return _validator
454
454
455
455
456 def ValidForkType(old_data={}):
456 def ValidForkType(old_data={}):
457 class _validator(formencode.validators.FancyValidator):
457 class _validator(formencode.validators.FancyValidator):
458 messages = {
458 messages = {
459 'invalid_fork_type': _(u'Fork have to be the same type as parent')
459 'invalid_fork_type': _(u'Fork have to be the same type as parent')
460 }
460 }
461
461
462 def validate_python(self, value, state):
462 def validate_python(self, value, state):
463 if old_data['repo_type'] != value:
463 if old_data['repo_type'] != value:
464 msg = M(self, 'invalid_fork_type', state)
464 msg = M(self, 'invalid_fork_type', state)
465 raise formencode.Invalid(msg, value, state,
465 raise formencode.Invalid(msg, value, state,
466 error_dict=dict(repo_type=msg)
466 error_dict=dict(repo_type=msg)
467 )
467 )
468 return _validator
468 return _validator
469
469
470
470
471 def CanWriteGroup():
471 def CanWriteGroup():
472 class _validator(formencode.validators.FancyValidator):
472 class _validator(formencode.validators.FancyValidator):
473 messages = {
473 messages = {
474 'permission_denied': _(u"You don't have permissions "
474 'permission_denied': _(u"You don't have permissions "
475 "to create repository in this group")
475 "to create repository in this group")
476 }
476 }
477
477
478 def to_python(self, value, state):
478 def to_python(self, value, state):
479 #root location
479 #root location
480 if value in [-1, "-1"]:
480 if value in [-1, "-1"]:
481 return None
481 return None
482 return value
482 return value
483
483
484 def validate_python(self, value, state):
484 def validate_python(self, value, state):
485 gr = RepoGroup.get(value)
485 gr = RepoGroup.get(value)
486 gr_name = gr.group_name if gr else None # None means ROOT location
486 gr_name = gr.group_name if gr else None # None means ROOT location
487 val = HasReposGroupPermissionAny('group.write', 'group.admin')
487 val = HasReposGroupPermissionAny('group.write', 'group.admin')
488 forbidden = not val(gr_name, 'can write into group validator')
488 forbidden = not val(gr_name, 'can write into group validator')
489 #parent group need to be existing
489 #parent group need to be existing
490 if gr and forbidden:
490 if gr and forbidden:
491 msg = M(self, 'permission_denied', state)
491 msg = M(self, 'permission_denied', state)
492 raise formencode.Invalid(msg, value, state,
492 raise formencode.Invalid(msg, value, state,
493 error_dict=dict(repo_type=msg)
493 error_dict=dict(repo_type=msg)
494 )
494 )
495 return _validator
495 return _validator
496
496
497
497
498 def CanCreateGroup(can_create_in_root=False):
498 def CanCreateGroup(can_create_in_root=False):
499 class _validator(formencode.validators.FancyValidator):
499 class _validator(formencode.validators.FancyValidator):
500 messages = {
500 messages = {
501 'permission_denied': _(u"You don't have permissions "
501 'permission_denied': _(u"You don't have permissions "
502 "to create a group in this location")
502 "to create a group in this location")
503 }
503 }
504
504
505 def to_python(self, value, state):
505 def to_python(self, value, state):
506 #root location
506 #root location
507 if value in [-1, "-1"]:
507 if value in [-1, "-1"]:
508 return None
508 return None
509 return value
509 return value
510
510
511 def validate_python(self, value, state):
511 def validate_python(self, value, state):
512 #TODO: REMOVE THIS !!
513 ################################
514 import ipdb;ipdb.set_trace()
515 print 'setting ipdb debuggin for rhodecode.model.validators._validator.validate_python'
516 ################################
517
518
519 gr = RepoGroup.get(value)
512 gr = RepoGroup.get(value)
520 gr_name = gr.group_name if gr else None # None means ROOT location
513 gr_name = gr.group_name if gr else None # None means ROOT location
521
514
522 if can_create_in_root and gr is None:
515 if can_create_in_root and gr is None:
523 #we can create in root, we're fine no validations required
516 #we can create in root, we're fine no validations required
524 return
517 return
525
518
526 forbidden_in_root = gr is None and can_create_in_root is False
519 forbidden_in_root = gr is None and can_create_in_root is False
527 val = HasReposGroupPermissionAny('group.admin')
520 val = HasReposGroupPermissionAny('group.admin')
528 forbidden = not val(gr_name, 'can create group validator')
521 forbidden = not val(gr_name, 'can create group validator')
529 if forbidden_in_root or forbidden:
522 if forbidden_in_root or forbidden:
530 msg = M(self, 'permission_denied', state)
523 msg = M(self, 'permission_denied', state)
531 raise formencode.Invalid(msg, value, state,
524 raise formencode.Invalid(msg, value, state,
532 error_dict=dict(group_parent_id=msg)
525 error_dict=dict(group_parent_id=msg)
533 )
526 )
534
527
535 return _validator
528 return _validator
536
529
537
530
538 def ValidPerms(type_='repo'):
531 def ValidPerms(type_='repo'):
539 if type_ == 'group':
532 if type_ == 'group':
540 EMPTY_PERM = 'group.none'
533 EMPTY_PERM = 'group.none'
541 elif type_ == 'repo':
534 elif type_ == 'repo':
542 EMPTY_PERM = 'repository.none'
535 EMPTY_PERM = 'repository.none'
543
536
544 class _validator(formencode.validators.FancyValidator):
537 class _validator(formencode.validators.FancyValidator):
545 messages = {
538 messages = {
546 'perm_new_member_name':
539 'perm_new_member_name':
547 _(u'This username or users group name is not valid')
540 _(u'This username or users group name is not valid')
548 }
541 }
549
542
550 def to_python(self, value, state):
543 def to_python(self, value, state):
551 perms_update = OrderedSet()
544 perms_update = OrderedSet()
552 perms_new = OrderedSet()
545 perms_new = OrderedSet()
553 # build a list of permission to update and new permission to create
546 # build a list of permission to update and new permission to create
554
547
555 #CLEAN OUT ORG VALUE FROM NEW MEMBERS, and group them using
548 #CLEAN OUT ORG VALUE FROM NEW MEMBERS, and group them using
556 new_perms_group = defaultdict(dict)
549 new_perms_group = defaultdict(dict)
557 for k, v in value.copy().iteritems():
550 for k, v in value.copy().iteritems():
558 if k.startswith('perm_new_member'):
551 if k.startswith('perm_new_member'):
559 del value[k]
552 del value[k]
560 _type, part = k.split('perm_new_member_')
553 _type, part = k.split('perm_new_member_')
561 args = part.split('_')
554 args = part.split('_')
562 if len(args) == 1:
555 if len(args) == 1:
563 new_perms_group[args[0]]['perm'] = v
556 new_perms_group[args[0]]['perm'] = v
564 elif len(args) == 2:
557 elif len(args) == 2:
565 _key, pos = args
558 _key, pos = args
566 new_perms_group[pos][_key] = v
559 new_perms_group[pos][_key] = v
567
560
568 # fill new permissions in order of how they were added
561 # fill new permissions in order of how they were added
569 for k in sorted(map(int, new_perms_group.keys())):
562 for k in sorted(map(int, new_perms_group.keys())):
570 perm_dict = new_perms_group[str(k)]
563 perm_dict = new_perms_group[str(k)]
571 new_member = perm_dict.get('name')
564 new_member = perm_dict.get('name')
572 new_perm = perm_dict.get('perm')
565 new_perm = perm_dict.get('perm')
573 new_type = perm_dict.get('type')
566 new_type = perm_dict.get('type')
574 if new_member and new_perm and new_type:
567 if new_member and new_perm and new_type:
575 perms_new.add((new_member, new_perm, new_type))
568 perms_new.add((new_member, new_perm, new_type))
576
569
577 for k, v in value.iteritems():
570 for k, v in value.iteritems():
578 if k.startswith('u_perm_') or k.startswith('g_perm_'):
571 if k.startswith('u_perm_') or k.startswith('g_perm_'):
579 member = k[7:]
572 member = k[7:]
580 t = {'u': 'user',
573 t = {'u': 'user',
581 'g': 'users_group'
574 'g': 'users_group'
582 }[k[0]]
575 }[k[0]]
583 if member == 'default':
576 if member == 'default':
584 if value.get('repo_private'):
577 if value.get('repo_private'):
585 # set none for default when updating to
578 # set none for default when updating to
586 # private repo
579 # private repo
587 v = EMPTY_PERM
580 v = EMPTY_PERM
588 perms_update.add((member, v, t))
581 perms_update.add((member, v, t))
589 #always set NONE when private flag is set
582 #always set NONE when private flag is set
590 if value.get('repo_private'):
583 if value.get('repo_private'):
591 perms_update.add(('default', EMPTY_PERM, 'user'))
584 perms_update.add(('default', EMPTY_PERM, 'user'))
592
585
593 value['perms_updates'] = list(perms_update)
586 value['perms_updates'] = list(perms_update)
594 value['perms_new'] = list(perms_new)
587 value['perms_new'] = list(perms_new)
595
588
596 # update permissions
589 # update permissions
597 for k, v, t in perms_new:
590 for k, v, t in perms_new:
598 try:
591 try:
599 if t is 'user':
592 if t is 'user':
600 self.user_db = User.query()\
593 self.user_db = User.query()\
601 .filter(User.active == True)\
594 .filter(User.active == True)\
602 .filter(User.username == k).one()
595 .filter(User.username == k).one()
603 if t is 'users_group':
596 if t is 'users_group':
604 self.user_db = UsersGroup.query()\
597 self.user_db = UsersGroup.query()\
605 .filter(UsersGroup.users_group_active == True)\
598 .filter(UsersGroup.users_group_active == True)\
606 .filter(UsersGroup.users_group_name == k).one()
599 .filter(UsersGroup.users_group_name == k).one()
607
600
608 except Exception:
601 except Exception:
609 log.exception('Updated permission failed')
602 log.exception('Updated permission failed')
610 msg = M(self, 'perm_new_member_type', state)
603 msg = M(self, 'perm_new_member_type', state)
611 raise formencode.Invalid(msg, value, state,
604 raise formencode.Invalid(msg, value, state,
612 error_dict=dict(perm_new_member_name=msg)
605 error_dict=dict(perm_new_member_name=msg)
613 )
606 )
614 return value
607 return value
615 return _validator
608 return _validator
616
609
617
610
618 def ValidSettings():
611 def ValidSettings():
619 class _validator(formencode.validators.FancyValidator):
612 class _validator(formencode.validators.FancyValidator):
620 def _to_python(self, value, state):
613 def _to_python(self, value, state):
621 # settings form for users that are not admin
614 # settings form for users that are not admin
622 # can't edit certain parameters, it's extra backup if they mangle
615 # can't edit certain parameters, it's extra backup if they mangle
623 # with forms
616 # with forms
624
617
625 forbidden_params = [
618 forbidden_params = [
626 'user', 'repo_type', 'repo_enable_locking',
619 'user', 'repo_type', 'repo_enable_locking',
627 'repo_enable_downloads', 'repo_enable_statistics'
620 'repo_enable_downloads', 'repo_enable_statistics'
628 ]
621 ]
629
622
630 for param in forbidden_params:
623 for param in forbidden_params:
631 if param in value:
624 if param in value:
632 del value[param]
625 del value[param]
633 return value
626 return value
634
627
635 def validate_python(self, value, state):
628 def validate_python(self, value, state):
636 pass
629 pass
637 return _validator
630 return _validator
638
631
639
632
640 def ValidPath():
633 def ValidPath():
641 class _validator(formencode.validators.FancyValidator):
634 class _validator(formencode.validators.FancyValidator):
642 messages = {
635 messages = {
643 'invalid_path': _(u'This is not a valid path')
636 'invalid_path': _(u'This is not a valid path')
644 }
637 }
645
638
646 def validate_python(self, value, state):
639 def validate_python(self, value, state):
647 if not os.path.isdir(value):
640 if not os.path.isdir(value):
648 msg = M(self, 'invalid_path', state)
641 msg = M(self, 'invalid_path', state)
649 raise formencode.Invalid(msg, value, state,
642 raise formencode.Invalid(msg, value, state,
650 error_dict=dict(paths_root_path=msg)
643 error_dict=dict(paths_root_path=msg)
651 )
644 )
652 return _validator
645 return _validator
653
646
654
647
655 def UniqSystemEmail(old_data={}):
648 def UniqSystemEmail(old_data={}):
656 class _validator(formencode.validators.FancyValidator):
649 class _validator(formencode.validators.FancyValidator):
657 messages = {
650 messages = {
658 'email_taken': _(u'This e-mail address is already taken')
651 'email_taken': _(u'This e-mail address is already taken')
659 }
652 }
660
653
661 def _to_python(self, value, state):
654 def _to_python(self, value, state):
662 return value.lower()
655 return value.lower()
663
656
664 def validate_python(self, value, state):
657 def validate_python(self, value, state):
665 if (old_data.get('email') or '').lower() != value:
658 if (old_data.get('email') or '').lower() != value:
666 user = User.get_by_email(value, case_insensitive=True)
659 user = User.get_by_email(value, case_insensitive=True)
667 if user:
660 if user:
668 msg = M(self, 'email_taken', state)
661 msg = M(self, 'email_taken', state)
669 raise formencode.Invalid(msg, value, state,
662 raise formencode.Invalid(msg, value, state,
670 error_dict=dict(email=msg)
663 error_dict=dict(email=msg)
671 )
664 )
672 return _validator
665 return _validator
673
666
674
667
675 def ValidSystemEmail():
668 def ValidSystemEmail():
676 class _validator(formencode.validators.FancyValidator):
669 class _validator(formencode.validators.FancyValidator):
677 messages = {
670 messages = {
678 'non_existing_email': _(u'e-mail "%(email)s" does not exist.')
671 'non_existing_email': _(u'e-mail "%(email)s" does not exist.')
679 }
672 }
680
673
681 def _to_python(self, value, state):
674 def _to_python(self, value, state):
682 return value.lower()
675 return value.lower()
683
676
684 def validate_python(self, value, state):
677 def validate_python(self, value, state):
685 user = User.get_by_email(value, case_insensitive=True)
678 user = User.get_by_email(value, case_insensitive=True)
686 if user is None:
679 if user is None:
687 msg = M(self, 'non_existing_email', state, email=value)
680 msg = M(self, 'non_existing_email', state, email=value)
688 raise formencode.Invalid(msg, value, state,
681 raise formencode.Invalid(msg, value, state,
689 error_dict=dict(email=msg)
682 error_dict=dict(email=msg)
690 )
683 )
691
684
692 return _validator
685 return _validator
693
686
694
687
695 def LdapLibValidator():
688 def LdapLibValidator():
696 class _validator(formencode.validators.FancyValidator):
689 class _validator(formencode.validators.FancyValidator):
697 messages = {
690 messages = {
698
691
699 }
692 }
700
693
701 def validate_python(self, value, state):
694 def validate_python(self, value, state):
702 try:
695 try:
703 import ldap
696 import ldap
704 ldap # pyflakes silence !
697 ldap # pyflakes silence !
705 except ImportError:
698 except ImportError:
706 raise LdapImportError()
699 raise LdapImportError()
707
700
708 return _validator
701 return _validator
709
702
710
703
711 def AttrLoginValidator():
704 def AttrLoginValidator():
712 class _validator(formencode.validators.FancyValidator):
705 class _validator(formencode.validators.FancyValidator):
713 messages = {
706 messages = {
714 'invalid_cn':
707 'invalid_cn':
715 _(u'The LDAP Login attribute of the CN must be specified - '
708 _(u'The LDAP Login attribute of the CN must be specified - '
716 'this is the name of the attribute that is equivalent '
709 'this is the name of the attribute that is equivalent '
717 'to "username"')
710 'to "username"')
718 }
711 }
719
712
720 def validate_python(self, value, state):
713 def validate_python(self, value, state):
721 if not value or not isinstance(value, (str, unicode)):
714 if not value or not isinstance(value, (str, unicode)):
722 msg = M(self, 'invalid_cn', state)
715 msg = M(self, 'invalid_cn', state)
723 raise formencode.Invalid(msg, value, state,
716 raise formencode.Invalid(msg, value, state,
724 error_dict=dict(ldap_attr_login=msg)
717 error_dict=dict(ldap_attr_login=msg)
725 )
718 )
726
719
727 return _validator
720 return _validator
728
721
729
722
730 def NotReviewedRevisions(repo_id):
723 def NotReviewedRevisions(repo_id):
731 class _validator(formencode.validators.FancyValidator):
724 class _validator(formencode.validators.FancyValidator):
732 messages = {
725 messages = {
733 'rev_already_reviewed':
726 'rev_already_reviewed':
734 _(u'Revisions %(revs)s are already part of pull request '
727 _(u'Revisions %(revs)s are already part of pull request '
735 'or have set status')
728 'or have set status')
736 }
729 }
737
730
738 def validate_python(self, value, state):
731 def validate_python(self, value, state):
739 # check revisions if they are not reviewed, or a part of another
732 # check revisions if they are not reviewed, or a part of another
740 # pull request
733 # pull request
741 statuses = ChangesetStatus.query()\
734 statuses = ChangesetStatus.query()\
742 .filter(ChangesetStatus.revision.in_(value))\
735 .filter(ChangesetStatus.revision.in_(value))\
743 .filter(ChangesetStatus.repo_id == repo_id)\
736 .filter(ChangesetStatus.repo_id == repo_id)\
744 .all()
737 .all()
745
738
746 errors = []
739 errors = []
747 for cs in statuses:
740 for cs in statuses:
748 if cs.pull_request_id:
741 if cs.pull_request_id:
749 errors.append(['pull_req', cs.revision[:12]])
742 errors.append(['pull_req', cs.revision[:12]])
750 elif cs.status:
743 elif cs.status:
751 errors.append(['status', cs.revision[:12]])
744 errors.append(['status', cs.revision[:12]])
752
745
753 if errors:
746 if errors:
754 revs = ','.join([x[1] for x in errors])
747 revs = ','.join([x[1] for x in errors])
755 msg = M(self, 'rev_already_reviewed', state, revs=revs)
748 msg = M(self, 'rev_already_reviewed', state, revs=revs)
756 raise formencode.Invalid(msg, value, state,
749 raise formencode.Invalid(msg, value, state,
757 error_dict=dict(revisions=revs)
750 error_dict=dict(revisions=revs)
758 )
751 )
759
752
760 return _validator
753 return _validator
761
754
762
755
763 def ValidIp():
756 def ValidIp():
764 class _validator(CIDR):
757 class _validator(CIDR):
765 messages = dict(
758 messages = dict(
766 badFormat=_('Please enter a valid IPv4 or IpV6 address'),
759 badFormat=_('Please enter a valid IPv4 or IpV6 address'),
767 illegalBits=_('The network size (bits) must be within the range'
760 illegalBits=_('The network size (bits) must be within the range'
768 ' of 0-32 (not %(bits)r)'))
761 ' of 0-32 (not %(bits)r)'))
769
762
770 def to_python(self, value, state):
763 def to_python(self, value, state):
771 v = super(_validator, self).to_python(value, state)
764 v = super(_validator, self).to_python(value, state)
772 v = v.strip()
765 v = v.strip()
773 net = ipaddr.IPNetwork(address=v)
766 net = ipaddr.IPNetwork(address=v)
774 if isinstance(net, ipaddr.IPv4Network):
767 if isinstance(net, ipaddr.IPv4Network):
775 #if IPv4 doesn't end with a mask, add /32
768 #if IPv4 doesn't end with a mask, add /32
776 if '/' not in value:
769 if '/' not in value:
777 v += '/32'
770 v += '/32'
778 if isinstance(net, ipaddr.IPv6Network):
771 if isinstance(net, ipaddr.IPv6Network):
779 #if IPv6 doesn't end with a mask, add /128
772 #if IPv6 doesn't end with a mask, add /128
780 if '/' not in value:
773 if '/' not in value:
781 v += '/128'
774 v += '/128'
782 return v
775 return v
783
776
784 def validate_python(self, value, state):
777 def validate_python(self, value, state):
785 try:
778 try:
786 addr = value.strip()
779 addr = value.strip()
787 #this raises an ValueError if address is not IpV4 or IpV6
780 #this raises an ValueError if address is not IpV4 or IpV6
788 ipaddr.IPNetwork(address=addr)
781 ipaddr.IPNetwork(address=addr)
789 except ValueError:
782 except ValueError:
790 raise formencode.Invalid(self.message('badFormat', state),
783 raise formencode.Invalid(self.message('badFormat', state),
791 value, state)
784 value, state)
792
785
793 return _validator
786 return _validator
General Comments 0
You need to be logged in to leave comments. Login now