Authentication Issue

Hi,

I’ve my app working on production with no problems except the reset password code bit.

This is my urls.py for the user app

urlpatterns = [
    path('admin/', admin.site.urls),
    path('register/', user_views.register, name='register'),
    path('profile/', user_views.profile, name='profile'),
    path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'),
    path('logout/', auth_views.LogoutView.as_view(template_name='users/logout.html'), name='logout'),
    path('password-reset/',
         auth_views.PasswordResetView.as_view(template_name='users/password_reset.html'),
         name='password_reset'),
    path('password-reset/done',
         auth_views.PasswordResetDoneView.as_view(template_name='users/password_reset_done.html'),
         name='password_reset_done'),
    path('password-reset-confirm/<uidb64>/<token>/',
         auth_views.PasswordResetConfirmView.as_view(template_name='users/password_reset_confirm.html'),
         name='password_reset_confirm'),
    path('password-reset-complete/',
         auth_views.PasswordResetCompleteView.as_view(template_name='users/password_reset_complete.html'),
         name='password_reset_complete'),
    path('', include('books.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

This is my settings.py

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.sendgrid.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = os.environ.get('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_HOST_PASSWORD')

When I try to reset the password I get this error message:

# SMTPSenderRefused at /password-reset/

I’ve stored the username and password on local variables and they seem to be working but when the error pops-up I can see in the settings part that the EMAIL_HOST_USER is set to none

Screenshot 2023-02-18 at 16.26.38

I’ve been able to send a message from the production server with telnet through the SendGrid SMTP Relay.

What is happening here? Why is the username none in the settings on the debug?

Any help would be much appreciated.
Miguel

The most direct and obvious initial explanation is that you don’t have an environment variable named EMAIL_HOST_USER in the environment in which you’re running Django.

You can verify this by setting a default value in the get function to see if that’s what’s being applied.

Resolving this requires knowledge of how you’re running your Django app and how you’re setting the environment for those processes.

The environment variables are defined in the .profile file and the system can see them, as you can see from the picture.
Screenshot 2023-02-18 at 17.51.17

Ok, you’ve defined them in a .profile file.

How are you running your Django instance, and how are the entries in that file being added to that process’ environment? (Hint: That second part doesn’t happen automatically with a non-login shell.)

Are you talking about .env file? Do I need to install django-environ and declare all my environment variables there, and then update the settings.py accordingly?

Can you do it that way? Yes.
Is the the only way? No
Is it the “best” way? That depends…

I really can’t answer your question until you answer mine. Off the top of my head, I can think of at least 30 different ways to run a Django environment, each providing slightly different mechanisms for managing the environment, including the “in app” method you identify.

I’m using a VM with ubuntu, nginx and gunicorn

DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION=“Ubuntu 22.04.1 LTS”

nginx version: nginx/1.18.0 (Ubuntu)

gunicorn (version 20.1.0)

How are you running gunicorn? Systemd, supervisord, runit, init.d, docker, ???

I’m really new to this, so I have to ask, how do I know/check that?

“Something” is running gunicorn. You would have had to set it up to run - all those options above involve manual steps to get started.

When your server is booted, it’s not going to run gunicorn unless you’ve done something to make it start gunicorn after a boot. I’m trying to learn what that “something”, is.

I haven’t done nothing, I think the server had already that “something” working. The only thing I have is a file called gunicorn.py that is on /etc/gunicorn.d

"""gunicorn WSGI server configuration."""
from multiprocessing import cpu_count
from os import environ


def max_workers():
    return cpu_count() * 2 + 1

max_requests = 1000
worker_class = 'gevent'
workers = max_workers()

So you’re working from a server that someone else configured? (This doesn’t happen magically or automatically, someone configured gunicorn to start after a system reboot.)

If that’s the case, you’d need to do some sleuthing to try and figure out what started gunicorn.

For example, you could start with the command (as root):
ps -AF | grep gunicorn
That’s going to hopefully show a line starting with a user in the first column, then two columns of numbers. If the second number is “1”, then odds are you’ve got this set up as a systemd task. If it’s not a “1”, then the command:
ps -AF | grep <number from second column>
should reveal the identity of the parent process.

I think it’s 1

Great!

That’s a fairly distinctive command line there - now it’s just a matter of finding what file contains that command.

You would likely find it somewhere in the /etc directory, possibly under /etc/systemd if that’s what’s being used to run it.

I think i found it.
gunicorn.service on
/etc/systemd/system

[Unit]
Description=Gunicorn daemon for Django Project
Before=nginx.service
After=network.target

[Service]
WorkingDirectory=/home/django/django_books
ExecStart=/usr/bin/gunicorn3 --name=django_books --pythonpath=/home/django/django_books --bind unix:/home/django/gunicorn.socket >
Restart=always
SyslogIdentifier=gunicorn
User=django
Group=django


[Install]
WantedBy=multi-user.target

Yep, that would be it.

That gives you a couple different ways to do this.

First, you do have the option of using django-environ.

Second, you can use the env parameter on the ExecStart command to specify those settings with the command. (Or, on a related theme, you can put them in a configuration file and point gunicorn to use that file for its settings.)

Finally, there’s an Environment command available for within the service files. (See Ubuntu Manpage: systemd.exec - Execution environment configuration)

Any one of the three will work. The one you choose really is up to you - what makes the most sense to you.

Ken, I’m trying with the django-environ option but now I get this error:

SMTPServerDisconnected at /password-reset/

Connection unexpectedly closed

What could that be?

In the general case, that’s going to be caused by incorrect connection settings. It could be an incorrect password, or it could be some other connection setting. From what I can see here, my guess is that your password isn’t correct for the user you’re trying to use.

Hi Ken, it’s working, finally! There was some incorrect information, you were right, has always. Thank you very much for this BIG BIG help.
Cheers