I was looking through the code for this module, and I can't use it as-is because .state defines User = get_user_model(). It would be nice if I could authenticate different tables against different user models.
In the system I'm building, I want the AUTH_USER_MODEL table to be "company employee" users only, and I want "customer" users to be in a separate table. (There may be company employees in the latter table, but we don't want their accounts connected.)
Also, django.contrib.auth makes demands on the user model that I don't want applied to the customer model, especially given the admin interface.
So, to do this, I'd like to just connect the appropriate authentication and permissions plugins for that table. Which means the things in .state probably need to not be globals.
I think I just need to take the global-dependent stuff and make a class out of it.
Existing functionality could be maintained by making the current functionality the default.
Do you have a better idea? Would you you interested in pull requests from this fork?
Well, that turned out to be much easier than anticipated. Passes all 122 tests. Now I need to figure out some tests for the custom user (as opposed to get_user_model) route. And add this to the README.
All I had to do was replace:
from .state import User
with:
from django.contrib.auth import get_user_model
# ...
class JWTAuthentication(...):
# ...
user_class = get_user_model()
Then the couple places that used User changed to use self.user_class instead. Nothing changes for existing uses of DRF_SJWT, and if you want to use a different user class, you just do:
from rest_framework_simplejwt.authentication import JWTAuthentication
from .models import Customer
class CustJWTAuthentication(JWTAuthentication):
user_class = Customer
and then you just use CustJWTAuthentication instead of JWTAuthentication in your ViewSet'sauthentication_classes.
rest_framework_simplejwt.authentication.JWTTokenUserAuthentication required no changes.
The state.py file is no longer used and was removed. The token_backend stuff it had moved into tokens.Token similar to how User was moved above. The four tests that pulled in state were adjusted to remove the dependency (test_authentication.py was already changed).
Actually, I really like where you're going with this. If you want to create a PR, I'll probably merge it in. I feel like having those class properties opens up the ability for people to more easily customize the way things work. It would be nice to have some tests that run through those customizations and then eventually some documentation to describe it.
In writing the tests, I'm noticing some other things like dependencies on api_settings, which can be resolved by similar means. So there's a bit more work to go.
But it's going well so far. Tricky mocking up a couple classes to act like a custom user table without actually making a Django model out of it (which would require populating tests/models.py and writing migrations and so forth.)
(i.e. the user ID field name needs to be overridable but default to api_settings.USER_ID_FIELD)
Python makes stuff too easy.
Well, only one tox test fails:
INTERNALERROR> ImportError: cannot import name 'six' from 'django.utils' ([...]/venv/src/djangorestframework-simplejwt/.tox/py37-djangomaster-drf39/lib/python3.7/site-packages/django/utils/__init__.py)
Seems like a nothingburger, really. Should I do anything about it?
How's that PR going @davesque? I did a very similar 'workaround' for my case and would appreciate having this in next release :)
yes +1 for this
Do we have some progress in this feature? Please for merge ;)