##// END OF EJS Templates
fixed bug when user is capable of creating _admin repository which is a link to admin interface
marcink -
r310:fc4027fe default
parent child Browse files
Show More
@@ -1,240 +1,242 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 from formencode import All
22 from formencode import All
23 from formencode.validators import UnicodeString, OneOf, Int, Number, Regex, \
23 from formencode.validators import UnicodeString, OneOf, Int, Number, Regex, \
24 Email, Bool, StringBoolean
24 Email, Bool, StringBoolean
25 from pylons import session
25 from pylons import session
26 from pylons.i18n.translation import _
26 from pylons.i18n.translation import _
27 from pylons_app.lib.auth import get_crypt_password
27 from pylons_app.lib.auth import get_crypt_password
28 import pylons_app.lib.helpers as h
28 import pylons_app.lib.helpers as h
29 from pylons_app.model import meta
29 from pylons_app.model import meta
30 from pylons_app.model.db import User, Repository
30 from pylons_app.model.db import User, Repository
31 from sqlalchemy.exc import OperationalError
31 from sqlalchemy.exc import OperationalError
32 from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
32 from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
33 from webhelpers.pylonslib.secure_form import authentication_token
33 from webhelpers.pylonslib.secure_form import authentication_token
34 import datetime
34 import datetime
35 import formencode
35 import formencode
36 import logging
36 import logging
37 log = logging.getLogger(__name__)
37 log = logging.getLogger(__name__)
38
38
39
39
40 #this is needed to translate the messages using _() in validators
40 #this is needed to translate the messages using _() in validators
41 class State_obj(object):
41 class State_obj(object):
42 _ = staticmethod(_)
42 _ = staticmethod(_)
43
43
44 #===============================================================================
44 #===============================================================================
45 # VALIDATORS
45 # VALIDATORS
46 #===============================================================================
46 #===============================================================================
47 class ValidAuthToken(formencode.validators.FancyValidator):
47 class ValidAuthToken(formencode.validators.FancyValidator):
48 messages = {'invalid_token':_('Token mismatch')}
48 messages = {'invalid_token':_('Token mismatch')}
49
49
50 def validate_python(self, value, state):
50 def validate_python(self, value, state):
51
51
52 if value != authentication_token():
52 if value != authentication_token():
53 raise formencode.Invalid(self.message('invalid_token', state,
53 raise formencode.Invalid(self.message('invalid_token', state,
54 search_number=value), value, state)
54 search_number=value), value, state)
55 class ValidUsername(formencode.validators.FancyValidator):
55 class ValidUsername(formencode.validators.FancyValidator):
56
56
57 def validate_python(self, value, state):
57 def validate_python(self, value, state):
58 if value in ['default', 'new_user']:
58 if value in ['default', 'new_user']:
59 raise formencode.Invalid(_('Invalid username'), value, state)
59 raise formencode.Invalid(_('Invalid username'), value, state)
60
60
61 class ValidPassword(formencode.validators.FancyValidator):
61 class ValidPassword(formencode.validators.FancyValidator):
62
62
63 def to_python(self, value, state):
63 def to_python(self, value, state):
64 return get_crypt_password(value)
64 return get_crypt_password(value)
65
65
66 class ValidAuth(formencode.validators.FancyValidator):
66 class ValidAuth(formencode.validators.FancyValidator):
67 messages = {
67 messages = {
68 'invalid_password':_('invalid password'),
68 'invalid_password':_('invalid password'),
69 'invalid_login':_('invalid user name'),
69 'invalid_login':_('invalid user name'),
70 'disabled_account':_('Your acccount is disabled')
70 'disabled_account':_('Your acccount is disabled')
71
71
72 }
72 }
73 #error mapping
73 #error mapping
74 e_dict = {'username':messages['invalid_login'],
74 e_dict = {'username':messages['invalid_login'],
75 'password':messages['invalid_password']}
75 'password':messages['invalid_password']}
76 e_dict_disable = {'username':messages['disabled_account']}
76 e_dict_disable = {'username':messages['disabled_account']}
77
77
78 def validate_python(self, value, state):
78 def validate_python(self, value, state):
79 sa = meta.Session
79 sa = meta.Session
80 crypted_passwd = get_crypt_password(value['password'])
80 crypted_passwd = get_crypt_password(value['password'])
81 username = value['username']
81 username = value['username']
82 try:
82 try:
83 user = sa.query(User).filter(User.username == username).one()
83 user = sa.query(User).filter(User.username == username).one()
84 except (NoResultFound, MultipleResultsFound, OperationalError) as e:
84 except (NoResultFound, MultipleResultsFound, OperationalError) as e:
85 log.error(e)
85 log.error(e)
86 user = None
86 user = None
87 raise formencode.Invalid(self.message('invalid_password',
87 raise formencode.Invalid(self.message('invalid_password',
88 state=State_obj), value, state,
88 state=State_obj), value, state,
89 error_dict=self.e_dict)
89 error_dict=self.e_dict)
90 if user:
90 if user:
91 if user.active:
91 if user.active:
92 if user.username == username and user.password == crypted_passwd:
92 if user.username == username and user.password == crypted_passwd:
93 from pylons_app.lib.auth import AuthUser
93 from pylons_app.lib.auth import AuthUser
94 auth_user = AuthUser()
94 auth_user = AuthUser()
95 auth_user.username = username
95 auth_user.username = username
96 auth_user.is_authenticated = True
96 auth_user.is_authenticated = True
97 auth_user.is_admin = user.admin
97 auth_user.is_admin = user.admin
98 auth_user.user_id = user.user_id
98 auth_user.user_id = user.user_id
99 session['hg_app_user'] = auth_user
99 session['hg_app_user'] = auth_user
100 session.save()
100 session.save()
101 log.info('user %s is now authenticated', username)
101 log.info('user %s is now authenticated', username)
102
102
103 try:
103 try:
104 user.last_login = datetime.datetime.now()
104 user.last_login = datetime.datetime.now()
105 sa.add(user)
105 sa.add(user)
106 sa.commit()
106 sa.commit()
107 except (OperationalError) as e:
107 except (OperationalError) as e:
108 log.error(e)
108 log.error(e)
109 sa.rollback()
109 sa.rollback()
110
110
111 return value
111 return value
112 else:
112 else:
113 log.warning('user %s not authenticated', username)
113 log.warning('user %s not authenticated', username)
114 raise formencode.Invalid(self.message('invalid_password',
114 raise formencode.Invalid(self.message('invalid_password',
115 state=State_obj), value, state,
115 state=State_obj), value, state,
116 error_dict=self.e_dict)
116 error_dict=self.e_dict)
117 else:
117 else:
118 log.warning('user %s is disabled', username)
118 log.warning('user %s is disabled', username)
119 raise formencode.Invalid(self.message('disabled_account',
119 raise formencode.Invalid(self.message('disabled_account',
120 state=State_obj),
120 state=State_obj),
121 value, state,
121 value, state,
122 error_dict=self.e_dict_disable)
122 error_dict=self.e_dict_disable)
123
123
124
124
125 class ValidRepoUser(formencode.validators.FancyValidator):
125 class ValidRepoUser(formencode.validators.FancyValidator):
126
126
127 def to_python(self, value, state):
127 def to_python(self, value, state):
128 sa = meta.Session
128 sa = meta.Session
129 try:
129 try:
130 self.user_db = sa.query(User).filter(User.username == value).one()
130 self.user_db = sa.query(User).filter(User.username == value).one()
131 except Exception:
131 except Exception:
132 raise formencode.Invalid(_('This username is not valid'),
132 raise formencode.Invalid(_('This username is not valid'),
133 value, state)
133 value, state)
134 return self.user_db.user_id
134 return self.user_db.user_id
135
135
136 def ValidRepoName(edit=False):
136 def ValidRepoName(edit=False):
137 class _ValidRepoName(formencode.validators.FancyValidator):
137 class _ValidRepoName(formencode.validators.FancyValidator):
138
138
139 def to_python(self, value, state):
139 def to_python(self, value, state):
140 slug = h.repo_name_slug(value)
140 slug = h.repo_name_slug(value)
141
141 if slug in ['_admin']:
142 raise formencode.Invalid(_('This repository name is disallowed'),
143 value, state)
142 sa = meta.Session
144 sa = meta.Session
143 if sa.query(Repository).get(slug) and not edit:
145 if sa.query(Repository).get(slug) and not edit:
144 raise formencode.Invalid(_('This repository already exists'),
146 raise formencode.Invalid(_('This repository already exists'),
145 value, state)
147 value, state)
146
148
147 return slug
149 return slug
148 return _ValidRepoName
150 return _ValidRepoName
149
151
150 class ValidPerms(formencode.validators.FancyValidator):
152 class ValidPerms(formencode.validators.FancyValidator):
151 messages = {'perm_new_user_name':_('This username is not valid')}
153 messages = {'perm_new_user_name':_('This username is not valid')}
152
154
153 def to_python(self, value, state):
155 def to_python(self, value, state):
154 perms_update = []
156 perms_update = []
155 perms_new = []
157 perms_new = []
156 #build a list of permission to update and new permission to create
158 #build a list of permission to update and new permission to create
157 for k, v in value.items():
159 for k, v in value.items():
158 if k.startswith('perm_'):
160 if k.startswith('perm_'):
159 if k.startswith('perm_new_user'):
161 if k.startswith('perm_new_user'):
160 new_perm = value.get('perm_new_user', False)
162 new_perm = value.get('perm_new_user', False)
161 new_user = value.get('perm_new_user_name', False)
163 new_user = value.get('perm_new_user_name', False)
162 if new_user and new_perm:
164 if new_user and new_perm:
163 if (new_user, new_perm) not in perms_new:
165 if (new_user, new_perm) not in perms_new:
164 perms_new.append((new_user, new_perm))
166 perms_new.append((new_user, new_perm))
165 else:
167 else:
166 usr = k[5:]
168 usr = k[5:]
167 if usr == 'default':
169 if usr == 'default':
168 if value['private']:
170 if value['private']:
169 #set none for default when updating to private repo
171 #set none for default when updating to private repo
170 v = 'repository.none'
172 v = 'repository.none'
171 perms_update.append((usr, v))
173 perms_update.append((usr, v))
172 value['perms_updates'] = perms_update
174 value['perms_updates'] = perms_update
173 value['perms_new'] = perms_new
175 value['perms_new'] = perms_new
174 sa = meta.Session
176 sa = meta.Session
175 for k, v in perms_new:
177 for k, v in perms_new:
176 try:
178 try:
177 self.user_db = sa.query(User).filter(User.username == k).one()
179 self.user_db = sa.query(User).filter(User.username == k).one()
178 except Exception:
180 except Exception:
179 msg = self.message('perm_new_user_name',
181 msg = self.message('perm_new_user_name',
180 state=State_obj)
182 state=State_obj)
181 raise formencode.Invalid(msg, value, state, error_dict={'perm_new_user_name':msg})
183 raise formencode.Invalid(msg, value, state, error_dict={'perm_new_user_name':msg})
182 return value
184 return value
183
185
184 #===============================================================================
186 #===============================================================================
185 # FORMS
187 # FORMS
186 #===============================================================================
188 #===============================================================================
187 class LoginForm(formencode.Schema):
189 class LoginForm(formencode.Schema):
188 allow_extra_fields = True
190 allow_extra_fields = True
189 filter_extra_fields = True
191 filter_extra_fields = True
190 username = UnicodeString(
192 username = UnicodeString(
191 strip=True,
193 strip=True,
192 min=3,
194 min=3,
193 not_empty=True,
195 not_empty=True,
194 messages={
196 messages={
195 'empty':_('Please enter a login'),
197 'empty':_('Please enter a login'),
196 'tooShort':_('Enter a value %(min)i characters long or more')}
198 'tooShort':_('Enter a value %(min)i characters long or more')}
197 )
199 )
198
200
199 password = UnicodeString(
201 password = UnicodeString(
200 strip=True,
202 strip=True,
201 min=3,
203 min=3,
202 not_empty=True,
204 not_empty=True,
203 messages={
205 messages={
204 'empty':_('Please enter a password'),
206 'empty':_('Please enter a password'),
205 'tooShort':_('Enter a value %(min)i characters long or more')}
207 'tooShort':_('Enter a value %(min)i characters long or more')}
206 )
208 )
207
209
208
210
209 #chained validators have access to all data
211 #chained validators have access to all data
210 chained_validators = [ValidAuth]
212 chained_validators = [ValidAuth]
211
213
212 def UserForm(edit=False):
214 def UserForm(edit=False):
213 class _UserForm(formencode.Schema):
215 class _UserForm(formencode.Schema):
214 allow_extra_fields = True
216 allow_extra_fields = True
215 filter_extra_fields = True
217 filter_extra_fields = True
216 username = All(UnicodeString(strip=True, min=3, not_empty=True), ValidUsername)
218 username = All(UnicodeString(strip=True, min=3, not_empty=True), ValidUsername)
217 if edit:
219 if edit:
218 new_password = All(UnicodeString(strip=True, min=3, not_empty=False), ValidPassword)
220 new_password = All(UnicodeString(strip=True, min=3, not_empty=False), ValidPassword)
219 else:
221 else:
220 password = All(UnicodeString(strip=True, min=3, not_empty=False), ValidPassword)
222 password = All(UnicodeString(strip=True, min=3, not_empty=False), ValidPassword)
221 active = StringBoolean(if_missing=False)
223 active = StringBoolean(if_missing=False)
222 name = UnicodeString(strip=True, min=3, not_empty=True)
224 name = UnicodeString(strip=True, min=3, not_empty=True)
223 lastname = UnicodeString(strip=True, min=3, not_empty=True)
225 lastname = UnicodeString(strip=True, min=3, not_empty=True)
224 email = Email(not_empty=True)
226 email = Email(not_empty=True)
225
227
226 return _UserForm
228 return _UserForm
227
229
228 def RepoForm(edit=False):
230 def RepoForm(edit=False):
229 class _RepoForm(formencode.Schema):
231 class _RepoForm(formencode.Schema):
230 allow_extra_fields = True
232 allow_extra_fields = True
231 filter_extra_fields = False
233 filter_extra_fields = False
232 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit))
234 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), ValidRepoName(edit))
233 description = UnicodeString(strip=True, min=3, not_empty=True)
235 description = UnicodeString(strip=True, min=3, not_empty=True)
234 private = StringBoolean(if_missing=False)
236 private = StringBoolean(if_missing=False)
235
237
236 if edit:
238 if edit:
237 user = All(Int(not_empty=True), ValidRepoUser)
239 user = All(Int(not_empty=True), ValidRepoUser)
238
240
239 chained_validators = [ValidPerms]
241 chained_validators = [ValidPerms]
240 return _RepoForm
242 return _RepoForm
General Comments 0
You need to be logged in to leave comments. Login now