1. Gregory Petukhov
  2. django-urlauth
Issue #4 resolved

Approximately 50% of users authenticate wrong.

Taras Liapun
created an issue

try: {{{

!python

class TestUrlAuth(TestCase):

def test_url_auth(self):
    fails = 0
    for i in xrange(0, 100):
        user = any_model(User, active=True)
        url = AuthKey.objects.wrap_url(reverse('homepage'),
                                                uid=user.pk)
        response = self.client.get(url)
        try:
            self.assertContains(response, user.first_name)
        except AssertionError:
            fails += 1 
        self.client.logout()
    print 'fails: ', fails

}}} You can see something like: "fails: 55"

It is a pity that I did this test after the start of use :(

Or may I do something wrong?

Comments (11)

  1. Taras Liapun reporter

    Oh sorry, my mistake here:

    user = any_model(User, active=True)
    

    Must be:

    user = any_model(User, is_active=True)
    

    But anyway we got a problem with an incorrect user authorization. Trying to unserstand the reason...

  2. Taras Liapun reporter

    Found the cause.

    See:

    Traceback (most recent call last):
      File "manage.py", line 11, in <module>
        execute_manager(settings)
      File ".env/lib/python2.7/site-packages/django/core/management/__init__.py", line 438, in execute_manager
        utility.execute()
      File ".env/lib/python2.7/site-packages/django/core/management/__init__.py", line 379, in execute
        self.fetch_command(subcommand).run_from_argv(self.argv)
      File ".env/lib/python2.7/site-packages/django/core/management/base.py", line 191, in run_from_argv
        self.execute(*args, **options.__dict__)
      File ".env/lib/python2.7/site-packages/django/core/management/base.py", line 220, in execute
        output = self.handle(*args, **options)
      File "core/management/commands/send.py", line 57, in handle
        uid=user.pk)
      File ".env/lib/python2.7/site-packages/urlauth/models.py", line 42, in wrap_url
        key_id = self.create_key(**kwargs)
      File ".env/lib/python2.7/site-packages/urlauth/models.py", line 34, in create_key
        key.save()
      File ".env/lib/python2.7/site-packages/django/db/models/base.py", line 434, in save
        self.save_base(using=using, force_insert=force_insert, force_update=force_update)
      File ".env/lib/python2.7/site-packages/django/db/models/base.py", line 500, in save_base
        rows = manager.using(using).filter(pk=pk_val)._update(values)
      File ".env/lib/python2.7/site-packages/django/db/models/query.py", line 491, in _update
        return query.get_compiler(self.db).execute_sql(None)
      File ".env/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 861, in execute_sql
        cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)
      File ".env/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 727, in execute_sql
        cursor.execute(sql, params)
      File ".env/lib/python2.7/site-packages/django/db/backends/util.py", line 15, in execute
        return self.cursor.execute(sql, params)
      File ".env/lib/python2.7/site-packages/django/db/backends/mysql/base.py", line 86, in execute
        return self.cursor.execute(query, args)
      File ".env/lib/python2.7/site-packages/MySQLdb/cursors.py", line 176, in execute
        if not self._defer_warnings: self._warning_check()
      File ".env/lib/python2.7/site-packages/MySQLdb/cursors.py", line 92, in _warning_check
        warn(w[-1], self.Warning, 3)
    _mysql_exceptions.Warning: Column 'created' cannot be null
    

    And see here - http://stackoverflow.com/questions/1737017/django-auto-now-and-auto-now-add

  3. Taras Liapun reporter

    Very simple:

    from django.contrib.auth.models import User
    
    from django_any import any_model
    from urlauth.models import AuthKey
    
    
    def reproduce():
        for i in xrange(0, 100):
            any_model(User, is_active=True)
    
        users = User.objects.all()
    
        for user in users:
            AuthKey.objects.wrap_url('/', uid=user.pk)
    
  4. Gregory Petukhov repo owner

    Trying to reproduce the error. Also I do not understand the solution. Yes, I know that auto_now_add could be rewritten with custom save method, but I'm trying find out why the auto_now_add is the problem.

    There is some mystic. I've started to write the code which reproduces the error. And I've got the error as you described. But then I've changed something, and since that moment I can't catch error anymore :-/ All things work fine.

    I've pushed demo project with test.py script which is similar to the code you've provided. Does it raise the error on your machine? Or maybe you could change it somehow so it begins to fail?

    Demo: https://bitbucket.org/lorien/django-urlauth/src/ee42aa8d34e1/demo/

  5. Gregory Petukhov repo owner

    The problem was in algorithm of calculation unique keys. Keys are not unique enough so sometimes django-urlauth tries to save new key with hash which is already in database. AuthKey instances store the hash in primary key field. When django tries to save the object which primary key is already in database it does UPDATE instead of INSERT. So django tries to update details of existing object with details of objects which is not saved yet and which created field is NULL. What is why you've got the "Column 'created' cannot be null" message.

    I've changed the algorithm of unique hash generation, also I've changed the logic of saving new AuthKey objects. You can see details here: https://bitbucket.org/lorien/django-urlauth/changeset/b49d0d4bb533

    Please confirm that you have no errors anymore on your machine.

  6. Log in to comment