##// END OF EJS Templates
fix private flag switching default permission
marcink -
r3217:f5c5095c beta
parent child Browse files
Show More
@@ -1,742 +1,742 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 validate_python(self, value, state):
478 def validate_python(self, value, state):
479 gr = RepoGroup.get(value)
479 gr = RepoGroup.get(value)
480 if not HasReposGroupPermissionAny(
480 if not HasReposGroupPermissionAny(
481 'group.write', 'group.admin'
481 'group.write', 'group.admin'
482 )(gr.group_name, 'get group of repo form'):
482 )(gr.group_name, 'get group of repo form'):
483 msg = M(self, 'permission_denied', state)
483 msg = M(self, 'permission_denied', state)
484 raise formencode.Invalid(msg, value, state,
484 raise formencode.Invalid(msg, value, state,
485 error_dict=dict(repo_type=msg)
485 error_dict=dict(repo_type=msg)
486 )
486 )
487 return _validator
487 return _validator
488
488
489
489
490 def ValidPerms(type_='repo'):
490 def ValidPerms(type_='repo'):
491 if type_ == 'group':
491 if type_ == 'group':
492 EMPTY_PERM = 'group.none'
492 EMPTY_PERM = 'group.none'
493 elif type_ == 'repo':
493 elif type_ == 'repo':
494 EMPTY_PERM = 'repository.none'
494 EMPTY_PERM = 'repository.none'
495
495
496 class _validator(formencode.validators.FancyValidator):
496 class _validator(formencode.validators.FancyValidator):
497 messages = {
497 messages = {
498 'perm_new_member_name':
498 'perm_new_member_name':
499 _(u'This username or users group name is not valid')
499 _(u'This username or users group name is not valid')
500 }
500 }
501
501
502 def to_python(self, value, state):
502 def to_python(self, value, state):
503 perms_update = OrderedSet()
503 perms_update = OrderedSet()
504 perms_new = OrderedSet()
504 perms_new = OrderedSet()
505 # build a list of permission to update and new permission to create
505 # build a list of permission to update and new permission to create
506
506
507 #CLEAN OUT ORG VALUE FROM NEW MEMBERS, and group them using
507 #CLEAN OUT ORG VALUE FROM NEW MEMBERS, and group them using
508 new_perms_group = defaultdict(dict)
508 new_perms_group = defaultdict(dict)
509 for k, v in value.copy().iteritems():
509 for k, v in value.copy().iteritems():
510 if k.startswith('perm_new_member'):
510 if k.startswith('perm_new_member'):
511 del value[k]
511 del value[k]
512 _type, part = k.split('perm_new_member_')
512 _type, part = k.split('perm_new_member_')
513 args = part.split('_')
513 args = part.split('_')
514 if len(args) == 1:
514 if len(args) == 1:
515 new_perms_group[args[0]]['perm'] = v
515 new_perms_group[args[0]]['perm'] = v
516 elif len(args) == 2:
516 elif len(args) == 2:
517 _key, pos = args
517 _key, pos = args
518 new_perms_group[pos][_key] = v
518 new_perms_group[pos][_key] = v
519
519
520 # fill new permissions in order of how they were added
520 # fill new permissions in order of how they were added
521 for k in sorted(map(int, new_perms_group.keys())):
521 for k in sorted(map(int, new_perms_group.keys())):
522 perm_dict = new_perms_group[str(k)]
522 perm_dict = new_perms_group[str(k)]
523 new_member = perm_dict.get('name')
523 new_member = perm_dict.get('name')
524 new_perm = perm_dict.get('perm')
524 new_perm = perm_dict.get('perm')
525 new_type = perm_dict.get('type')
525 new_type = perm_dict.get('type')
526 if new_member and new_perm and new_type:
526 if new_member and new_perm and new_type:
527 perms_new.add((new_member, new_perm, new_type))
527 perms_new.add((new_member, new_perm, new_type))
528
528
529 for k, v in value.iteritems():
529 for k, v in value.iteritems():
530 if k.startswith('u_perm_') or k.startswith('g_perm_'):
530 if k.startswith('u_perm_') or k.startswith('g_perm_'):
531 member = k[7:]
531 member = k[7:]
532 t = {'u': 'user',
532 t = {'u': 'user',
533 'g': 'users_group'
533 'g': 'users_group'
534 }[k[0]]
534 }[k[0]]
535 if member == 'default':
535 if member == 'default':
536 if value.get('private'):
536 if value.get('repo_private'):
537 # set none for default when updating to
537 # set none for default when updating to
538 # private repo
538 # private repo
539 v = EMPTY_PERM
539 v = EMPTY_PERM
540 perms_update.add((member, v, t))
540 perms_update.add((member, v, t))
541
541
542 value['perms_updates'] = list(perms_update)
542 value['perms_updates'] = list(perms_update)
543 value['perms_new'] = list(perms_new)
543 value['perms_new'] = list(perms_new)
544
544
545 # update permissions
545 # update permissions
546 for k, v, t in perms_new:
546 for k, v, t in perms_new:
547 try:
547 try:
548 if t is 'user':
548 if t is 'user':
549 self.user_db = User.query()\
549 self.user_db = User.query()\
550 .filter(User.active == True)\
550 .filter(User.active == True)\
551 .filter(User.username == k).one()
551 .filter(User.username == k).one()
552 if t is 'users_group':
552 if t is 'users_group':
553 self.user_db = UsersGroup.query()\
553 self.user_db = UsersGroup.query()\
554 .filter(UsersGroup.users_group_active == True)\
554 .filter(UsersGroup.users_group_active == True)\
555 .filter(UsersGroup.users_group_name == k).one()
555 .filter(UsersGroup.users_group_name == k).one()
556
556
557 except Exception:
557 except Exception:
558 log.exception('Updated permission failed')
558 log.exception('Updated permission failed')
559 msg = M(self, 'perm_new_member_type', state)
559 msg = M(self, 'perm_new_member_type', state)
560 raise formencode.Invalid(msg, value, state,
560 raise formencode.Invalid(msg, value, state,
561 error_dict=dict(perm_new_member_name=msg)
561 error_dict=dict(perm_new_member_name=msg)
562 )
562 )
563 return value
563 return value
564 return _validator
564 return _validator
565
565
566
566
567 def ValidSettings():
567 def ValidSettings():
568 class _validator(formencode.validators.FancyValidator):
568 class _validator(formencode.validators.FancyValidator):
569 def _to_python(self, value, state):
569 def _to_python(self, value, state):
570 # settings form for users that are not admin
570 # settings form for users that are not admin
571 # can't edit certain parameters, it's extra backup if they mangle
571 # can't edit certain parameters, it's extra backup if they mangle
572 # with forms
572 # with forms
573
573
574 forbidden_params = [
574 forbidden_params = [
575 'user', 'repo_type', 'repo_enable_locking',
575 'user', 'repo_type', 'repo_enable_locking',
576 'repo_enable_downloads', 'repo_enable_statistics'
576 'repo_enable_downloads', 'repo_enable_statistics'
577 ]
577 ]
578
578
579 for param in forbidden_params:
579 for param in forbidden_params:
580 if param in value:
580 if param in value:
581 del value[param]
581 del value[param]
582 return value
582 return value
583
583
584 def validate_python(self, value, state):
584 def validate_python(self, value, state):
585 pass
585 pass
586 return _validator
586 return _validator
587
587
588
588
589 def ValidPath():
589 def ValidPath():
590 class _validator(formencode.validators.FancyValidator):
590 class _validator(formencode.validators.FancyValidator):
591 messages = {
591 messages = {
592 'invalid_path': _(u'This is not a valid path')
592 'invalid_path': _(u'This is not a valid path')
593 }
593 }
594
594
595 def validate_python(self, value, state):
595 def validate_python(self, value, state):
596 if not os.path.isdir(value):
596 if not os.path.isdir(value):
597 msg = M(self, 'invalid_path', state)
597 msg = M(self, 'invalid_path', state)
598 raise formencode.Invalid(msg, value, state,
598 raise formencode.Invalid(msg, value, state,
599 error_dict=dict(paths_root_path=msg)
599 error_dict=dict(paths_root_path=msg)
600 )
600 )
601 return _validator
601 return _validator
602
602
603
603
604 def UniqSystemEmail(old_data={}):
604 def UniqSystemEmail(old_data={}):
605 class _validator(formencode.validators.FancyValidator):
605 class _validator(formencode.validators.FancyValidator):
606 messages = {
606 messages = {
607 'email_taken': _(u'This e-mail address is already taken')
607 'email_taken': _(u'This e-mail address is already taken')
608 }
608 }
609
609
610 def _to_python(self, value, state):
610 def _to_python(self, value, state):
611 return value.lower()
611 return value.lower()
612
612
613 def validate_python(self, value, state):
613 def validate_python(self, value, state):
614 if (old_data.get('email') or '').lower() != value:
614 if (old_data.get('email') or '').lower() != value:
615 user = User.get_by_email(value, case_insensitive=True)
615 user = User.get_by_email(value, case_insensitive=True)
616 if user:
616 if user:
617 msg = M(self, 'email_taken', state)
617 msg = M(self, 'email_taken', state)
618 raise formencode.Invalid(msg, value, state,
618 raise formencode.Invalid(msg, value, state,
619 error_dict=dict(email=msg)
619 error_dict=dict(email=msg)
620 )
620 )
621 return _validator
621 return _validator
622
622
623
623
624 def ValidSystemEmail():
624 def ValidSystemEmail():
625 class _validator(formencode.validators.FancyValidator):
625 class _validator(formencode.validators.FancyValidator):
626 messages = {
626 messages = {
627 'non_existing_email': _(u'e-mail "%(email)s" does not exist.')
627 'non_existing_email': _(u'e-mail "%(email)s" does not exist.')
628 }
628 }
629
629
630 def _to_python(self, value, state):
630 def _to_python(self, value, state):
631 return value.lower()
631 return value.lower()
632
632
633 def validate_python(self, value, state):
633 def validate_python(self, value, state):
634 user = User.get_by_email(value, case_insensitive=True)
634 user = User.get_by_email(value, case_insensitive=True)
635 if user is None:
635 if user is None:
636 msg = M(self, 'non_existing_email', state, email=value)
636 msg = M(self, 'non_existing_email', state, email=value)
637 raise formencode.Invalid(msg, value, state,
637 raise formencode.Invalid(msg, value, state,
638 error_dict=dict(email=msg)
638 error_dict=dict(email=msg)
639 )
639 )
640
640
641 return _validator
641 return _validator
642
642
643
643
644 def LdapLibValidator():
644 def LdapLibValidator():
645 class _validator(formencode.validators.FancyValidator):
645 class _validator(formencode.validators.FancyValidator):
646 messages = {
646 messages = {
647
647
648 }
648 }
649
649
650 def validate_python(self, value, state):
650 def validate_python(self, value, state):
651 try:
651 try:
652 import ldap
652 import ldap
653 ldap # pyflakes silence !
653 ldap # pyflakes silence !
654 except ImportError:
654 except ImportError:
655 raise LdapImportError()
655 raise LdapImportError()
656
656
657 return _validator
657 return _validator
658
658
659
659
660 def AttrLoginValidator():
660 def AttrLoginValidator():
661 class _validator(formencode.validators.FancyValidator):
661 class _validator(formencode.validators.FancyValidator):
662 messages = {
662 messages = {
663 'invalid_cn':
663 'invalid_cn':
664 _(u'The LDAP Login attribute of the CN must be specified - '
664 _(u'The LDAP Login attribute of the CN must be specified - '
665 'this is the name of the attribute that is equivalent '
665 'this is the name of the attribute that is equivalent '
666 'to "username"')
666 'to "username"')
667 }
667 }
668
668
669 def validate_python(self, value, state):
669 def validate_python(self, value, state):
670 if not value or not isinstance(value, (str, unicode)):
670 if not value or not isinstance(value, (str, unicode)):
671 msg = M(self, 'invalid_cn', state)
671 msg = M(self, 'invalid_cn', state)
672 raise formencode.Invalid(msg, value, state,
672 raise formencode.Invalid(msg, value, state,
673 error_dict=dict(ldap_attr_login=msg)
673 error_dict=dict(ldap_attr_login=msg)
674 )
674 )
675
675
676 return _validator
676 return _validator
677
677
678
678
679 def NotReviewedRevisions(repo_id):
679 def NotReviewedRevisions(repo_id):
680 class _validator(formencode.validators.FancyValidator):
680 class _validator(formencode.validators.FancyValidator):
681 messages = {
681 messages = {
682 'rev_already_reviewed':
682 'rev_already_reviewed':
683 _(u'Revisions %(revs)s are already part of pull request '
683 _(u'Revisions %(revs)s are already part of pull request '
684 'or have set status')
684 'or have set status')
685 }
685 }
686
686
687 def validate_python(self, value, state):
687 def validate_python(self, value, state):
688 # check revisions if they are not reviewed, or a part of another
688 # check revisions if they are not reviewed, or a part of another
689 # pull request
689 # pull request
690 statuses = ChangesetStatus.query()\
690 statuses = ChangesetStatus.query()\
691 .filter(ChangesetStatus.revision.in_(value))\
691 .filter(ChangesetStatus.revision.in_(value))\
692 .filter(ChangesetStatus.repo_id == repo_id)\
692 .filter(ChangesetStatus.repo_id == repo_id)\
693 .all()
693 .all()
694
694
695 errors = []
695 errors = []
696 for cs in statuses:
696 for cs in statuses:
697 if cs.pull_request_id:
697 if cs.pull_request_id:
698 errors.append(['pull_req', cs.revision[:12]])
698 errors.append(['pull_req', cs.revision[:12]])
699 elif cs.status:
699 elif cs.status:
700 errors.append(['status', cs.revision[:12]])
700 errors.append(['status', cs.revision[:12]])
701
701
702 if errors:
702 if errors:
703 revs = ','.join([x[1] for x in errors])
703 revs = ','.join([x[1] for x in errors])
704 msg = M(self, 'rev_already_reviewed', state, revs=revs)
704 msg = M(self, 'rev_already_reviewed', state, revs=revs)
705 raise formencode.Invalid(msg, value, state,
705 raise formencode.Invalid(msg, value, state,
706 error_dict=dict(revisions=revs)
706 error_dict=dict(revisions=revs)
707 )
707 )
708
708
709 return _validator
709 return _validator
710
710
711
711
712 def ValidIp():
712 def ValidIp():
713 class _validator(CIDR):
713 class _validator(CIDR):
714 messages = dict(
714 messages = dict(
715 badFormat=_('Please enter a valid IPv4 or IpV6 address'),
715 badFormat=_('Please enter a valid IPv4 or IpV6 address'),
716 illegalBits=_('The network size (bits) must be within the range'
716 illegalBits=_('The network size (bits) must be within the range'
717 ' of 0-32 (not %(bits)r)'))
717 ' of 0-32 (not %(bits)r)'))
718
718
719 def to_python(self, value, state):
719 def to_python(self, value, state):
720 v = super(_validator, self).to_python(value, state)
720 v = super(_validator, self).to_python(value, state)
721 v = v.strip()
721 v = v.strip()
722 net = ipaddr.IPNetwork(address=v)
722 net = ipaddr.IPNetwork(address=v)
723 if isinstance(net, ipaddr.IPv4Network):
723 if isinstance(net, ipaddr.IPv4Network):
724 #if IPv4 doesn't end with a mask, add /32
724 #if IPv4 doesn't end with a mask, add /32
725 if '/' not in value:
725 if '/' not in value:
726 v += '/32'
726 v += '/32'
727 if isinstance(net, ipaddr.IPv6Network):
727 if isinstance(net, ipaddr.IPv6Network):
728 #if IPv6 doesn't end with a mask, add /128
728 #if IPv6 doesn't end with a mask, add /128
729 if '/' not in value:
729 if '/' not in value:
730 v += '/128'
730 v += '/128'
731 return v
731 return v
732
732
733 def validate_python(self, value, state):
733 def validate_python(self, value, state):
734 try:
734 try:
735 addr = value.strip()
735 addr = value.strip()
736 #this raises an ValueError if address is not IpV4 or IpV6
736 #this raises an ValueError if address is not IpV4 or IpV6
737 ipaddr.IPNetwork(address=addr)
737 ipaddr.IPNetwork(address=addr)
738 except ValueError:
738 except ValueError:
739 raise formencode.Invalid(self.message('badFormat', state),
739 raise formencode.Invalid(self.message('badFormat', state),
740 value, state)
740 value, state)
741
741
742 return _validator
742 return _validator
General Comments 0
You need to be logged in to leave comments. Login now