Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PasswordField does not seem to work with Postgres #766

Closed
yohanboniface opened this issue Nov 21, 2015 · 7 comments
Closed

PasswordField does not seem to work with Postgres #766

yohanboniface opened this issue Nov 21, 2015 · 7 comments

Comments

@yohanboniface
Copy link
Contributor

import peewee
from playhouse.fields import PasswordField

db = peewee.PostgresqlDatabase('peewee')


class User(peewee.Model):
    username = peewee.CharField(max_length=10)
    password = PasswordField()

    class Meta:
        database = db


if __name__ == '__main__':
    User.create_table()
    user = User.create(username='yo', password='password')
    user = User.get(User.id == user.id)
    assert user.password.check_password('password')

Fails with this traceback:

Traceback (most recent call last):
  File "peewee_password_field.py", line 22, in <module>
    user = User.get(User.id == user.id)
  File "/home/ybon/.virtualenvs/ban/lib/python3.4/site-packages/peewee.py", line 4393, in get
    return sq.get()
  File "/home/ybon/.virtualenvs/ban/lib/python3.4/site-packages/peewee.py", line 2812, in get
    return clone.execute().next()
  File "/home/ybon/.virtualenvs/ban/lib/python3.4/site-packages/peewee.py", line 2029, in next
    obj = self.iterate()
  File "/home/ybon/.virtualenvs/ban/lib/python3.4/site-packages/peewee.py", line 2015, in iterate
    return self.process_row(row)
  File "/home/ybon/.virtualenvs/ban/lib/python3.4/site-packages/peewee.py", line 2090, in process_row
    setattr(instance, column, func(row[i]))
  File "/home/ybon/.virtualenvs/ban/lib/python3.4/site-packages/playhouse/fields.py", line 66, in python_value
    return PasswordHash(value)
TypeError: string argument without an encoding

@yohanboniface
Copy link
Contributor Author

Thanks :)

@yohanboniface
Copy link
Contributor Author

Same code, with updated peewee:

Traceback (most recent call last):
  File "peewee_password_field.py", line 19, in <module>
    assert user.password.check_password('password')
  File "/home/ybon/.virtualenvs/p3/local/lib/python3.4/site-packages/playhouse/fields.py", line 47, in check_password
    return hashpw(password, self) == self
  File "/home/ybon/.virtualenvs/p3/local/lib/python3.4/site-packages/bcrypt/__init__.py", line 66, in hashpw
    raise ValueError("Invalid salt")
ValueError: Invalid salt

Missing unittests in Postgres? :)

@yohanboniface
Copy link
Contributor Author

(I can't reopen the issue, dunno why…)

@coleifer
Copy link
Owner

coleifer commented Dec 1, 2015

I'm not sure what's going on exactly. Having trouble getting bcrypt to build in a python3 virtualenv but testing locally with python2+sqlite is working fine. What is the salt of the particular password you're having trouble with, and what is it's type?

@yohanboniface
Copy link
Contributor Author

Thanks for looking into this @coleifer :)

I'm just running the snippet from #766 (comment) (I'm on IRC if it helps debugging).

@yohanboniface
Copy link
Contributor Author

This diff fixes my usecase:

diff --git a/playhouse/fields.py b/playhouse/fields.py
index fcebae7..bfa2d90 100644
--- a/playhouse/fields.py
+++ b/playhouse/fields.py
@@ -47,7 +47,7 @@ if hashpw and gensalt:
             return hashpw(password, self) == self


-    class PasswordField(TextField):
+    class PasswordField(BlobField):
         def __init__(self, iterations=12, *args, **kwargs):
             if None in (hashpw, gensalt):
                 raise ValueError('Missing library required for PasswordField: bcrypt')

Basically, the issue seems to be that we are sending bytes to a Text field in Postgres.
Not sure though why tests passe without this change (they also pass with the fix)…

@yohanboniface
Copy link
Contributor Author

Ah, now I know why tests passe even without the fix: they are never ran with postgres…
Even if I pass --engine postgres, simply because the Model used in the tests only use "in memory database": https://github.com/coleifer/peewee/blob/master/playhouse/tests/test_extra_fields.py#L22

Is there a reason for that?

yohanboniface added a commit to yohanboniface/peewee that referenced this issue Dec 23, 2015
This also makes the tests be ran with postgres.
coleifer added a commit that referenced this issue Dec 28, 2015
Fix PasswordField on postgres (fix #766)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants