Commits

Chris Hasenpflug  committed f1448cb

Create a util for converting to django's password format

  • Participants
  • Parent commits a140d13
  • Branches xf-auth

Comments (0)

Files changed (3)

File xenforo/backends.py

 import phpserialize
 
 from .conf import settings
-from .utils import dictfetchall
+from .utils import dictfetchall, convert_to_django_password
 
 
 class XFAuthBackend(object):
     """
-    Authenticates against settings.AUTH_USER_MODEL.
+    Checks for a XenForo user, and if found, creates a settings.AUTH_USER_MODEL
+    and authenticates against it.
     """
 
     def authenticate(self, username=None, password=None, **kwargs):
             'defaults': {'pk': row['user_id'],
                          'is_staff': True,
                          'is_superuser': True,
-                         'password': 'xenforo_core12${0}'.format(phpserialize.unserialize(row['data'], decode_strings=True)['hash'])
+                         'password': convert_to_django_password(row['scheme_class'], row['data'])
                         }
         })
 
         if not created:
-            user.password = 'xenforo_core12${0}'.format(phpserialize.unserialize(row['data'], decode_strings=True)['hash'])
+            user.password = convert_to_django_password(row['scheme_class'], row['data'])
             user.save()
 
         if user.check_password(password):

File xenforo/tests/test_utils.py

+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from unittest import TestCase
+
+from ..utils import convert_to_django_password
+
+class TestUtils(TestCase):
+
+    def test_core12(self):
+        scheme_class = 'XenForo_Authentication_Core12'
+        data = b'a:1:{s:4:"hash";s:60:"$2a$10$EnvKvs.royUb7HV2lBGAROLdwbghtS4KBlaDrkFoFa3sIAmPn6gk6";}'
+        self.assertEqual(
+            convert_to_django_password(scheme_class, data),
+            'xenforo_core12$$2a$10$EnvKvs.royUb7HV2lBGAROLdwbghtS4KBlaDrkFoFa3sIAmPn6gk6'
+        )
+
+    def test_core_sha256(self):
+        scheme_class = 'XenForo_Authentication_Core'
+        data = b'a:3:{s:4:"hash";s:64:"38d61fda7efdc4122b3a5a36f2a548ec72bd013a9ce05b4404f412b00089517a";s:4:"salt";s:7:"seasalt";s:8:"hashFunc";s:6:"sha256";}'
+        self.assertEqual(
+            convert_to_django_password(scheme_class, data),
+            'xenforo_sha256$seasalt$38d61fda7efdc4122b3a5a36f2a548ec72bd013a9ce05b4404f412b00089517a'
+        )
+
+    def test_core_sha1(self):
+        scheme_class = 'XenForo_Authentication_Core'
+        data = b'a:3:{s:4:"hash";s:40:"ccb1e9f3865a8f03a26b8d7f76139268f5d1e9e6";s:4:"salt";s:7:"seasalt";s:8:"hashFunc";s:4:"sha1";}'
+        self.assertEqual(
+            convert_to_django_password(scheme_class, data),
+            'xenforo_sha1$seasalt$ccb1e9f3865a8f03a26b8d7f76139268f5d1e9e6'
+        )
+
+    def test_vbulletin_md5(self):
+        scheme_class = 'XenForo_Authentication_vBulletin'
+        data = b'a:2:{s:4:"hash";s:32:"2800981dde706669ac6e5fb521e2b44b";s:4:"salt";s:3:"abc";}'
+        self.assertEqual(
+            convert_to_django_password(scheme_class, data),
+            'vbulletin_md5$abc$2800981dde706669ac6e5fb521e2b44b'
+        )

File xenforo/utils.py

+import phpserialize
 
 def dictfetchall(cursor):
     "Returns all rows from a cursor as a dict"
         dict(zip([col[0] for col in desc], row))
         for row in cursor.fetchall()
     ]
+
+
+def convert_to_django_password(scheme_class, data):
+    data = phpserialize.unserialize(data, decode_strings=True)
+
+    if scheme_class == 'XenForo_Authentication_Core12':
+        return 'xenforo_core12${hash}'.format(**data)
+    elif scheme_class == 'XenForo_Authentication_Core':
+        if data['hashFunc'] == 'sha256':
+            return 'xenforo_sha256${salt}${hash}'.format(**data)
+        if data['hashFunc'] == 'sha1':
+            return 'xenforo_sha1${salt}${hash}'.format(**data)
+    elif scheme_class == 'XenForo_Authentication_vBulletin':
+        return 'vbulletin_md5${salt}${hash}'.format(**data)