sklarsa / django-sendgrid-v5

An implementation of Django's EmailBackend compatible with sendgrid-python v5+
MIT License
318 stars 54 forks source link

Email fails when using django-allauth #65

Closed timwilson closed 4 years ago

timwilson commented 4 years ago

I'm working on getting SendGrid going and am having trouble with a 403 error when sending the Django user creation confirmation emails through SendGrid.

Here's what I have in my settings:

# settings.py
# SendGrid configuration
# EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
EMAIL_BACKEND = 'sendgrid_backend.SendgridBackend'
SENDGRID_API_KEY = os.environ.get("SENDGRID_API_KEY")
SENDGRID_SANDBOX_MODE_IN_DEBUG=False
SENDGRID_ECHO_TO_STDOUT=True

Here's the error I'm getting after submitting the signup form that's part of the django-allauth package:

Environment:
Request Method: POST
Request URL: http://localhost:8000/accounts/signup/

Django Version: 3.0.5
Python Version: 3.7.6
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'whitenoise.runserver_nostatic',
 'django.contrib.staticfiles',
 'django.contrib.sites',
 'django.contrib.humanize',
 'fontawesome_5',
 'sorl.thumbnail',
 'django_instagram',
 'allauth',
 'allauth.account',
 'crispy_forms',
 'debug_toolbar',
 'storages',
 'widget_tweaks',
 'bootstrap_modal_forms',
 'rules.apps.AutodiscoverRulesConfig',
 'hitcount',
 'sendgrid',
 'progear.apps.ProgearConfig',
 'users.apps.UsersConfig']
Installed Middleware:
['debug_toolbar.middleware.DebugToolbarMiddleware',
 'django.middleware.cache.UpdateCacheMiddleware',
 'django.middleware.security.SecurityMiddleware',
 'whitenoise.middleware.WhiteNoiseMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/python_http_client/client.py", line 174, in _make_request
    return opener.open(request, timeout=timeout)
  File "/usr/local/lib/python3.7/urllib/request.py", line 531, in open
    response = meth(req, response)
  File "/usr/local/lib/python3.7/urllib/request.py", line 641, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/local/lib/python3.7/urllib/request.py", line 569, in error
    return self._call_chain(*args)
  File "/usr/local/lib/python3.7/urllib/request.py", line 503, in _call_chain
    result = func(*args)
  File "/usr/local/lib/python3.7/urllib/request.py", line 649, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)

During handling of the above exception (HTTP Error 403: Forbidden), another exception occurred:
  File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.7/site-packages/django/views/generic/base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/django/utils/decorators.py", line 43, in _wrapper
    return bound_method(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/django/views/decorators/debug.py", line 76, in sensitive_post_parameters_wrapper
    return view(request, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/views.py", line 215, in dispatch
    return super(SignupView, self).dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/views.py", line 81, in dispatch
    **kwargs)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/views.py", line 193, in dispatch
    **kwargs)
  File "/usr/local/lib/python3.7/site-packages/django/views/generic/base.py", line 97, in dispatch
    return handler(request, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/views.py", line 104, in post
    response = self.form_valid(form)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/views.py", line 236, in form_valid
    self.get_success_url())
  File "/usr/local/lib/python3.7/site-packages/allauth/account/utils.py", line 192, in complete_signup
    signal_kwargs=signal_kwargs)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/utils.py", line 152, in perform_login
    send_email_confirmation(request, user, signup=signup)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/utils.py", line 323, in send_email_confirmation
    signup=signup)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/models.py", line 58, in send_confirmation
    confirmation.send(request, signup=signup)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/models.py", line 163, in send
    get_adapter(request).send_confirmation_mail(request, self, signup)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/adapter.py", line 450, in send_confirmation_mail
    ctx)
  File "/usr/local/lib/python3.7/site-packages/allauth/account/adapter.py", line 137, in send_mail
    msg.send()
  File "/usr/local/lib/python3.7/site-packages/django/core/mail/message.py", line 276, in send
    return self.get_connection(fail_silently).send_messages([self])
  File "/usr/local/lib/python3.7/site-packages/sendgrid_backend/mail.py", line 122, in send_messages
    resp = self.sg.client.mail.send.post(request_body=data)
  File "/usr/local/lib/python3.7/site-packages/python_http_client/client.py", line 262, in http_request
    self._make_request(opener, request, timeout=timeout)
  File "/usr/local/lib/python3.7/site-packages/python_http_client/client.py", line 178, in _make_request
    raise exc

Exception Type: ForbiddenError at /accounts/signup/
Exception Value: HTTP Error 403: Forbidden

If I turn off debug mode, I get a server error: "POST /accounts/signup/ HTTP/1.1" 500 145

I'm not even sure that this is related to the SendGrid integration, but when I bypass it, everything seems to work fine.

Any ideas what's going on?

sklarsa commented 4 years ago

This looks like a permissions issue on the Sendgrid side. I would double-check the settings from your successful test email vs the settings your application is currently using, paying close attention to the API Key and its permissions in Sendgrid.

If you still have issues, I would maybe try raising the issue in sendgrid-python, since I believe that is maintained by sendgrid itself.

timwilson commented 4 years ago

@sklarsa Thanks for the info. I'll work on that today and report back in this thread when I get it working so others might benefit.

dwjorgeb commented 4 years ago

@timwilson did you solve it? I'm having the same issue...

dwjorgeb commented 4 years ago

I think I solved it.

I went into https://app.sendgrid.com/settings/sender_auth/domains then on my verified domain I clicked on Use as default domain, after that it works like a charm.

Before that, the from email had to be @emXXXX.mydomain.com otherwise I'd get the 403 error.

This is a very easy solution but I feel that Sendgrid should either:

1 - When you have only 1 domain validated, automatically set it as the default one 2 - Clearly document that you either need to set the domain as default, or you'll need to send emails from the random subdomain you set up.

sklarsa commented 4 years ago

Thanks for looking into this @dwjorgeb!

timwilson commented 4 years ago

Good detective work, @dwjorgeb.

ptsteadman commented 3 years ago

I had to set DEFAULT_FROM_EMAIL = foo@mydomain.com to get this to work. The 'use as default domain' fix seems to have no effect. shrug