Migrating user accounts from Joomla to Django

I am rebuilding the site that I originally created using Joomla in Django, and I was wondering if I could import user entries directly from Joomla (my main problem is user passwords, because they are encrypted).

+4
source share
4 answers

Yes you can, but you will need to do some work. Joomla stores users in a specific DB table structure, so you have to pull them out and insert them into the user table that you create in your Django application. As for encryption, if the algorithm is known, this is probably the hash value stored in the database, and you can just pass it as is - as long as you implement the same hash algorithm in your Django application.

Remember: Django is a more general concept than Joomla - it is a medium for writing a web application, so theoretically you can even fully implement Joomla with it.

+3
source

I think there are three ways to solve this problem:

1) You can read about how joomla and django create a password hash and migrate using a script
2) You can make your own authentication backend
3) You can use the ETL tool

+1
source

Joomla (PHP) is the CMS, and Django (Python) is the web framework.

I wonder if this is really possible. At this point, I can conclude that it is impossible . However, someone may have any idea about this.

Thanks:)

0
source

Joomla users in Django (Django authentication backend that populates users from Joomla)

I once needed to use our existing Joomla users in my new Django API. The problem is that I could not just copy Joomla users to the Django database, because:

  • Joomla's password hashing system is different from Django.
  • J-users and D-users had a different set of fields (this is easy to fix, but still)

So instead, I made a custom authentication backend for Django, and now I can confidently say that

Django can authenticate users using the Joomla database, without having to decrypt password hashes or copy all users from Joomla DB at the same time.

Algorithm:

  • connect Joomla database to Django project
  • create a JoomlaUser model to populate users from the Joomla database
  • implement check_joomla_password() , which checks user passwords in the same way as Joomla
  • add a custom "Joomla Auth Backend" that copies each user from Joomla to Django the first time they log in

Implementation:

To understand what is going on, you must have some experience with Django. The code should be modified according to your django project. However, the code is taken from a working draft with minimal changes, and it should be easy to configure for your needs.

1. connect to Joomla DB:

 DATABASES = { 'default': {"your default DB settings"}, 'joomla_db': { 'ENGINE': 'django.db.backends.mysql', 'OPTIONS': {}, 'NAME': 'joomla_database_name', # Don't store passwords in the code, instead use env vars: 'USER': os.environ['joomla_db_user'], 'PASSWORD': os.environ['joomla_db_pass'], 'HOST': 'joomla_db_host, can be localhost or remote IP', 'PORT': '3306', } } # ensure that Joomla users are populated from the right database: DATABASE_ROUTERS = ['manager.router.DatabaseAppsRouter'] DATABASE_APPS_MAPPING = {'joomla_users': 'joomla_db'} # you also can create your own database router: # https://docs.djangoproject.com/en/dev/topics/db/multi-db/#automatic-database-routing # add logging to see Joomla DB requests: LOGGING = { 'version': 1, 'handlers': { 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'level': 'DEBUG', 'handlers': ['console'], }, }, } 

2. create a custom Joomla model

  • Read https://docs.djangoproject.com/en/2.1/howto/legacy-databases/
  • Think about where to save the new Joomla user model. In my project, I created a 'users' application "where my user models live and the custom Joomla backend will be hosted.
  • check how the user is stored in the existing Joomla database: python manage.py inspectdb --database="joomla_db"
  • Find and carefully study the user table.
  • Add to users/models.py :
 class JoomlaUser(models.Model): """ Represents our customer from the legacy Joomla database. """ username = models.CharField(max_length=150, primary_key=True) email = models.CharField(max_length=100) password = models.CharField(max_length=100) # you can copy more fields from 'inspectdb' output, # but it enough for the example class Meta: # joomla db user table. WARNING, your case can differs. db_table = 'live_users' # readonly managed = False # tip for the database router app_label = "joomla_users" 

Now go to the django ./manage.py shell and try to populate some users, for example

 >>> from users.models import JoomlaUser >>> print(JoomlaUser.objects.get(username='someuser')) JoomlaUser object (someuser) >>> 

If everything works, go to the next step. Otherwise, look at the errors, correct the settings, etc.

3. Verify Joomla User Passwords

Joomla does not store a user password, but a password hash, for example, $2y$10$aoZ4/bA7pe.QvjTU0R5.IeFGYrGag/THGvgKpoTk6bTz6XNkY0F2e

Starting with Joomla v3.2, user passwords are hashed using the BLOWFISH algorithm.

So, I downloaded the Python Blowfish implementation:

 pip install bcrypt echo bcrypt >> requirements.txt 

And created the Joomla password check function in users/backend.py :

 def check_joomla_password(password, hashed): """ Check if password matches the hashed password, using same hashing method (Blowfish) as Joomla >= 3.2 If you get wrong results with this function, check that the Hash starts from prefix "$2y", otherwise it is probably not a blowfish hash from Joomla. :return: True/False """ import bcrypt if password is None: return False # bcrypt requires byte strings password = password.encode('utf-8') hashed = hashed.encode('utf-8') return hashed == bcrypt.hashpw(password, hashed) 

Old versions Warning! Joomla <3.2 uses a different hashing method (md5 + salt), so this function will not work. In this case, read joomla's password encryption and implement hash verification in python, which will probably look something like this:

 # WARNING - THIS FUNCTION NOT TESTED WITH REAL JOOMLA USERS # and definitely has some errors def check_old_joomla_password(password, hashed): from hashlib import md5 password = password.encode('utf-8') hashed = hashed.encode('utf-8') if password is None: return False # check carefully this part: hash, salt = hashed.split(':') return hash == md5(password+salt).hexdigest() 

Unfortunately, the old Joomla instance does not work for me, so I could not test this feature for you.

4. Joomla Authentication Server

You are now ready to create a Joomla authentication backend for Django.

  1. Read how to change django authentication backends: https://docs.djangoproject.com/en/dev/topics/auth/customizing/

  2. Register the Jango backend (doesn't exist yet) in project/settings.py :

 AUTHENTICATION_BACKENDS = [ # Check if user already in the local DB # by using default django users backend 'django.contrib.auth.backends.ModelBackend', # If user was not found among django users, # use Joomla backend, which: # - search for user in Joomla DB # - check joomla user password # - copy joomla user into Django user. 'users.backend.JoomlaBackend', ] 
  1. Create Joomla Backend authentication in users/backend.py :
 from django.contrib.auth.models import User from .models import JoomlaUser """ check password function we wrote before """ def check_joomla_password(password, hashed): ... class JoomlaBackend: def authenticate(self, request, username=None, password=None): """ IF joomla user exists AND password is correct: create django user return user object ELSE: return None """ try: joomla_user = JoomlaUser.objects.get(username=username) except JoomlaUser.DoesNotExist: return None if check_joomla_password(password, joomla_user.password): # Password is correct, let create identical Django user: return User.objects.create_user( username=username, email=joomla_user.email, password=password, # any additional fields from the Joomla user: ... ) # this method is required to match Django Auth Backend interface def get_user(self, user_id): try: return User.objects.get(pk=user_id) except User.DoesNotExist: return None 

Test and documentation

Congratulations - now your customers from the old Joomla site can use their credentials on the new Django site or other APIs, etc.

Now add the appropriate tests and documentation to cover this new code. This logic is pretty tricky, so if you don’t do tests and documents (lazy dude), maintaining the project will be painful for your (or someone else's) ass.

Regards, @ Dmitry German

0
source

All Articles