-
Notifications
You must be signed in to change notification settings - Fork 348
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom auth backend compatibility for TenantClient #228
Conversation
**Rationale**: I'm creating a B2B multitenant app that logs in user using a custom auth backend which uses e-mail as one of the identifiers and authenticates users by parsing `request.META['HTTP_HOST']` to get the relevant schema. However, by doing this, I wasn't able to use `TenantClient`'s `login()` method since my custom auth backend needs a request object but django client's `login` method chain (`login -> authenticate(**credentials)->... ` [as shown here](https://github.com/django/django/blob/master/django/test/client.py#L594)) doesn't pass on a `request` object to my custom auth backend. Since I feel like B2B multitenant apps may often use custom auth backends like I did, I felt it necessary to propose this change.
@ishtiaque06 I can't see a problem this going in I will test it and merge in. Thanks Tom |
@ishtiaque06 Question: why not use the provided request factory? |
@lorinkoz I'm not sure I understand how I'd go about doing that. Could you point me to the right direction? |
Just read the docs. I will try this out to see if it works and keep you updated. Thank you! This is a much neater way of doing things (not up in the "Advanced Testing" alley yet). |
There is a I think this is the recommended way to create requests for testing. |
So I tried out EDIT: I know I probably would manually be able to synthesize all those aspects I wanted to test but it seems a little redundant if there's a global feature that enables me to do it for all tests I run using the test client. |
This is the custom authentication backend I'm trying to use if you want to work with it: from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model
from django_tenants.utils import schema_context
# Custom backend to enable logging in with e-mail.
# https://stackoverflow.com/questions/37332190/django-login-with-email
class EmailAuthBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, *args):
if request == None:
print ("args:", *args)
# schema = request.build_absolute_uri().split('.')[0].split('/')[-1]
schema = request.META['HTTP_HOST'].split('.')[0]
if (schema == 'dibs-test'):
return None
with schema_context(schema):
UserModel = get_user_model()
try:
user = UserModel.objects.get(email=username)
except UserModel.DoesNotExist:
return None
else:
if user.check_password(password):
return user
return None |
@ishtiaque06 Thanks I have committed this |
Rationale: I'm creating a B2B multitenant app that logs in user using a custom auth backend which uses e-mail as one of the identifiers and authenticates users by parsing
request.META['HTTP_HOST']
to get the relevant schema. However, by doing this, I wasn't able to useTenantClient
'slogin()
method since my custom auth backend needs a request object but django client'slogin
method chain (login -> authenticate(**credentials)->...
as shown here) doesn't pass on arequest
object to my custom auth backend.Since I feel like B2B multitenant apps may often use custom auth backends like I did, I felt it necessary to propose this change.