2

I have a project that uses Python 3.6 and Django 1.11 where I use the built-in User model.

The user objects are all inside the default database (which is postgres), but the project uses a second authentication backend because some users need to be authenticated against a legacy Oracle database.

# settings.py
AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',   # new postgres DB
    'project_config.auth_backends.OtherBackend',   # legacy Oracle DB
]

This works fine so far, but now I have 3 groups of users:

  • some users can only authenticate in ModelBackend because they are not in the legacy DB (because they are new users).
  • some users can only authenticate in the legacy DB; they have usr.has_usable_password() == False because they have not set their password in the new postgres DB yet.
  • some users can authenticate in both backends, maybe even with different passwords in each one; this is because they changed their password in the new system, but by design that change is not transmitted back to the legacy DB (don't shoot me, the only way to change the password in the legacy DB is to do it manually through the user interface).

For auditing purposes, I want to list all users and see which backends each one has available (ignoring the is_active flag for now) to make auditing tasks easier. My idea was to use a loop similar to this one:

for usr in User.objects.all():
    backend_list = []
    if usr.has_usable_password():
        backend_list.append('ModelBackend')
    if ... :                                  # what should I check here ?
        backend_list.append('OtherBackend')

    print(usr, backend_list)

I don't have the passwords for each user for the legacy database, so is may idea even possible?

I have not found a way, but I am open to suggestions.

Ralf
  • 16,086
  • 4
  • 44
  • 68
  • I think that the way to go would be to connect to your oracle dB and query the ‘users table’ (however it is done in oracle) to see if a user with that username exists. For that of course you need to have the right credentials – ivissani Nov 21 '18 at 14:15
  • You can check [this question](https://stackoverflow.com/questions/22451252/how-to-find-the-users-list-in-oracle-11g-db) on how to get oracle usernames – ivissani Nov 21 '18 at 14:26
  • And you can refer to [this site](https://www.oracle.com/technetwork/articles/dsl/python-091105.html) on how to connect to Oracle from python – ivissani Nov 21 '18 at 14:27
  • @ivissani yeah, that is also the only approach I could come up with so far. I already use `cx_Oracle` for my `OtherBackend`, so maybe I just need to set up credentials for a user with which I can access the user table in Oracle. – Ralf Nov 21 '18 at 15:31
  • According to [this part of the documentation](https://docs.djangoproject.com/es/2.1/topics/auth/customizing/#writing-an-authentication-backend) your authentication backend should have a `get_user` method that, given a `user_id` (whatever that is in your backend) returns a user object. I assume that you can call that method for every enabled backend and if you get `None` then your user cannot be authenticated by that particular backend. – ivissani Nov 21 '18 at 17:37

1 Answers1

0

In the end, I had to go with the suggestion from @ivissani and query the users table in the legacy Oracle DB:

select * from all_users;

With this information at hand, I could compare it to the users in the postgres DB and work out which users appear only in one or in both.

Ralf
  • 16,086
  • 4
  • 44
  • 68