login_bare custom validation

120 views
Skip to first unread message

DenesL

unread,
Oct 3, 2015, 7:58:52 PM10/3/15
to web2py-users
Hello all,

Trying to do a custom validation using login_bare, which I have never needed before, but I get a ticket shown below, it includes the minimalist code to reproduce it.
The view just shows the form.

Using authentication by username:
auth.define_tables(username=True, signature=False)

<type 'exceptions.TypeError'> 'LazyCrypt' object has no attribute '__getitem__'

web2py™ Version 2.12.3-stable+timestamp.2015.08.19.00.18.03

Traceback

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
Traceback (most recent call last):
File "C:\w2p\web2py_21203_src\gluon\restricted.py", line 227, in restricted
exec ccode in environment
File "C:/w2p/web2py_21203_src/applications/test/controllers/bare.py", line 34, in <module>
File "C:\w2p\web2py_21203_src\gluon\globals.py", line 412, in <lambda>
self._caller = lambda f: f()
File "C:/w2p/web2py_21203_src/applications/test/controllers/bare.py", line 13, in user
if form.validate(onvalidation=uservalidate, hideerror=True):
File "C:\w2p\web2py_21203_src\gluon\html.py", line 2238, in validate
if self.accepts(**kwargs):
File "C:\w2p\web2py_21203_src\gluon\sqlhtml.py", line 1496, in accepts
**kwargs
File "C:\w2p\web2py_21203_src\gluon\html.py", line 2139, in accepts
call_as_list(onvalidation, self)
File "C:\w2p\web2py_21203_src\gluon\html.py", line 146, in call_as_list
item(*a, **b)
File "C:/w2p/web2py_21203_src/applications/test/controllers/bare.py", line 26, in uservalidate
user = auth.login_bare(u, p)
File "C:\w2p\web2py_21203_src\gluon\tools.py", line 2352, in login_bare
settings.passfield].validate(password)[0]
File "C:\w2p\web2py_21203_src\gluon\packages\dal\pydal\objects.py", line 1625, in validate
(value, error) = validator(value)
File "C:\w2p\web2py_21203_src\gluon\validators.py", line 2850, in __call__
value = value and value[:self.max_length]
TypeError: 'LazyCrypt' object has no attribute '__getitem__'

In file: C:\w2p\web2py_21203_src\applications\test\controllers/bare.py

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
# -*- coding: utf-8 -*-
auth.settings.remember_me_form = False
auth.settings.login_url = URL('bare','user', args='login')


@auth.requires_login()
def index():
return {}


def user():
form = auth()
if form.validate(onvalidation=uservalidate, hideerror=True):
redirect(URL('bare', 'index'))
elif form.errors:
response.flash = ' '.join(form.errors.values())
return {'form':form}



def uservalidate(f):
u = f.vars.username or ''
p = f.vars.password or ''
print 'u: %s, p: %s' %(u,p)
if u and p:
user = auth.login_bare(u, p)
print user
if not user:
f.errors.password = 'Invalid Password'
return user
else:
return False

response._vars=response._caller(user)

Thanks for any hints,
Denes

DenesL

unread,
Oct 5, 2015, 7:54:18 AM10/5/15
to web2py-users
Hi again

alternatively, could anyone post some working code sample of using validation with login_bare?
the examples from the book and some posts in the forum were not enough for me.

Thanks,
Denes

DenesL

unread,
Oct 5, 2015, 2:51:22 PM10/5/15
to web2py-users
Tracing the execution it shows that the password is converted to a LazyCrypt object and then validated using the field's requires which uses Crypt.__call__ where this line


value = value and value[:self.max_length]

triggers a __getitem__ exception, since it is not defined in class LazyCrypt.

The easy solution is to add

value = str(value)

as the first in the Crypt.__call__ function.

Maybe there is a problem in the logic of login_bare but for now this works.
Here is me hoping nothing else breaks.

Denes   

DenesL

unread,
Oct 5, 2015, 4:06:33 PM10/5/15
to web2py-users
The error is gone but the login does not work.
This needs more thought.

DenesL

unread,
Oct 5, 2015, 4:33:48 PM10/5/15
to web2py-users
This seems to work:

   
def __call__(self, value):
        v
= str(value)
        v
= v and v[:self.max_length]
       
if len(v) < self.min_length:
           
return ('', translate(self.error_message))
       
if isinstance(value, LazyCrypt):
           
return (value, None)
       
return (LazyCrypt(self, value), None)

Massimo Di Pierro

unread,
Oct 7, 2015, 2:06:16 PM10/7/15
to web2py-users
welcome back Denes. :-) 
your fix is in trunk.

DenesL

unread,
Oct 7, 2015, 2:48:38 PM10/7/15
to web2py-users

Thanks Massimo
I never really went away ;-)
Reply all
Reply to author
Forward
0 new messages