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