On Thu, Sep 04, 2008 at 08:59:55PM +0200, Florian Haas wrote:
> class Credential(SQLObject):
>     class sqlmeta:
>         # necessary for the _set_passwd magic defined below
>         cacheValues = False
>     username = StringCol(alternateID=True, unique=True)
>     passwd = StringCol()
>     def _set_passwd(self, value):
>         # if the database has a built-in password hashing function,
>         # use it. Otherwise, store a SHA256 password hash
>         try:
>             self._SO_set_passwd(func.PASSWORD(value))
>         except:
>             digest = SHA256.new(value).hexdigest()
>             self._SO_set_passwd(digest)
> 
> So, thanks to Oleg's suggestions, this happily applies PASSWORD() when
> running on MySQL. Beautiful.
> 
> However, on a platform without PASSWORD() (tried sqlite), this happens:
> 
> >>> c = Credential(username="foo", passwd="bar")
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   [rest of stack trace...]
>   File
> "/usr/lib/python2.5/site-packages/sqlobject/sqlite/sqliteconnection.py",
> line 183, in _executeRetry
>     raise OperationalError(ErrorMessage(e))
> sqlobject.dberrors.OperationalError: no such function: PASSWORD
> 
> Huh? I said try..except, didn't I? As I said, this makes me feel totally
> braindead. Can someone whack me in the head and point me to the obvious
> thing I am missing?

   When the object is being created SQLObject doesn't set attributes one
by one - it collects all name/value pairs and then issues one INSERT query.
I.e., self._SO_set_passwd(func.PASSWORD(value)) doesn't access the SQL
backend and hence doesn't raise an exception; the exception is raised later,
when SQLObject really does INSERT.
   See main.py, method _SO_setValue() for details:

        if self.sqlmeta._creating:
            self._SO_createValues[name] = dbValue
            return

   (I simplified the real code a bit to stress the important points.)

   self._SO_set_passwd(func.PASSWORD(value)) will issue an immediate UPDATE
on any subsequent attribute assignment and your try/except will catch it.

   So for your magic to work you should create an object without a password
and then update the password:

c = Credential()
c.password = 'password'

   Change 'passwd' to StringCol(default=None).

Oleg.
-- 
     Oleg Broytmann            http://phd.pp.ru/            [EMAIL PROTECTED]
           Programmers don't die, they just GOSUB without RETURN.

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
sqlobject-discuss mailing list
sqlobject-discuss@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss

Reply via email to