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