Issues with sending forgot passwords links with Django + AWS SES

29 Views Asked by At

I'm trying to add a feature on my Django App to send users who forgot their passwords a link to reset them via email. I'm not sure if I have set up my password reset email feature correctly, or if my AWS SES isn't configured to it.

I have successfully sent email with a verified email in django shell with the method:

send_mail('title','message','[email protected]',['[email protected]])

Which means that I have configured my environment variables correctly, but incase you need to see it: Here's my Django Settings.py:


AWS_ACCESS_KEY_ID = env('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = env('AWS_SECRET_ACCESS_KEY')

EMAIL_BACKEND = 'django_ses.SESBackend'

AWS_SES_REGION_NAME = 'us-east-2'
AWS_SES_REGION_ENDPOINT = 'email.us-east-2.amazonaws.com'

Here are my files

views.py:

from re import search
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .forms import SignUpForm, AddRecordForm, RecordFilterForm, CustomUserChangeForm, CustomPasswordChangeForm
from .models import Record
from django.db.models import Q
from django.views.decorators.http import require_http_methods
from django.http import JsonResponse
from django.contrib.auth.forms import UserChangeForm
from django.core.exceptions import ValidationError
from django.contrib.auth import update_session_auth_hash
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger


#here is the homepage containing all the search filters
def home(request):
    records = Record.objects.all().order_by('created_at')
    search_form = RecordFilterForm(request.GET)
    
    if search_form.is_valid():
        search_query = search_form.cleaned_data.get('search')
        university_filter = search_form.cleaned_data.get('university_filter')
        course_name_filter = search_form.cleaned_data.get('course_name_filter')
        is_paid_filter = search_form.cleaned_data.get('is_paid')
        courses_filter = search_form.cleaned_data.get('course_category')
        duration_filter = search_form.cleaned_data.get('duration')
        gpa_filter = search_form.cleaned_data.get('gpa')

        if search_query:
            records = records.filter(
                Q(student_name__icontains=search_query) |
                Q(university__icontains=search_query) |
                Q(course_name__icontains=search_query) |
                Q(professor_name__icontains=search_query) |
                Q(description__icontains=search_query)
            )

        if university_filter:
            records = records.filter(university__icontains=university_filter)

        if course_name_filter:
            records = records.filter(course_name__icontains=course_name_filter)

        if is_paid_filter:
            records = records.filter(is_paid=is_paid_filter)

        if courses_filter:
            records = records.filter(course_category__iexact=courses_filter)

        if duration_filter:
            records = records.filter(duration=duration_filter)

        gpa_filter = search_form.cleaned_data.get('gpa')
        if gpa_filter:
            records = records.filter(result__startswith=gpa_filter)

    # Pagination
    page = request.GET.get('page', 1)
    paginator = Paginator(records, 15)

    try:
        records = paginator.page(page)
    except PageNotAnInteger:
        records = paginator.page(1)
    except EmptyPage:
        records = paginator.page(paginator.num_pages)

        
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(request, username=username, password=password)
        if user is not None:
            login(request, user)
            messages.success(request, "You Have Been Logged In!")
            return redirect('home')
        else:
            messages.success(request, "There Was An Error Logging In, Please Try Again...")
            return redirect('login')
    else:
        return render(request, 'home.html', {'records': records, 'search_form': search_form})

def login_user(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(request, username=username, password=password)

        if user is not None:
            login(request, user)
            messages.success(request, "You have been logged in successfully!")
            return redirect('home')
        else:
            messages.error(request, "Invalid login credentials. Please try again.")

    return render(request, 'login.html')




def profile(request):
    if request.user.is_authenticated:
        user_records = Record.objects.filter(created_by=request.user)
        bookmarked_records = Record.objects.filter(bookmarked_by=request.user)

        return render(request, 'profile.html', {
            'records': user_records,
            'bookmarked_records': bookmarked_records,
        })
    else:
        messages.success(request, "You must be logged in to view that page...")
        return redirect('home')




def logout_user(request):
    logout(request)
    messages.success(request, "You Have Been Logged Out...")
    return redirect('home')


def register_user(request):
    if request.method == 'POST':
        form = SignUpForm(request.POST)
        if form.is_valid():
            form.save()
            # Authenticate and login
            username = form.cleaned_data['username']
            password = form.cleaned_data['password1']
            user = authenticate(username=username, password=password)
            login(request, user)
            messages.success(request, "You Have Successfully Registered! Welcome!")
            return redirect('home')
    else:
        form = SignUpForm()
        return render(request, 'register.html', {'form':form})

    return render(request, 'register.html', {'form':form})

def update_profile(request):
    if request.method == 'POST':
        profile_form = CustomUserChangeForm(request.POST, instance=request.user)
        password_form = CustomPasswordChangeForm(request.user, request.POST)

        if profile_form.is_valid() and password_form.is_valid():
            profile_form.save()
            password_form.save()
            update_session_auth_hash(request, request.user)  # to avoid logging out after a password change
            messages.success(request, "Profile updated successfully!")
            return redirect('profile')
    else:
        profile_form = CustomUserChangeForm(instance=request.user)
        password_form = CustomPasswordChangeForm(request.user)

    return render(request, 'update_profile.html', {'profile_form': profile_form, 'password_form': password_form})


def delete_user(request):
    try:
        if request.user.is_authenticated:
            # Check if the user making the request is the account owner
            if request.user == request.user:
                user = request.user
                user.delete()
                messages.success(request, "Bye Bye!")
                return redirect('home')
            else:
                return JsonResponse({'error': 'You are not authorized to delete this account'}, status=403)
        else:
            return JsonResponse({'error': 'User not authenticated'}, status=401)
    except Exception as e:
        return redirect('home')


def customer_record(request, pk):
    try:
        customer_record = Record.objects.get(id=pk)
        
        # Check if the user has bookmarked the record
        is_bookmarked = False
        if request.user.is_authenticated:
            is_bookmarked = customer_record.bookmarked_by.filter(id=request.user.id).exists()

        if request.method == 'POST':
            if not request.user.is_authenticated:
                messages.success(request, "You must be logged in to perform this action.")
                return redirect('login')

            action = request.POST.get('action')

            if action == 'bookmark':
                customer_record.bookmarked_by.add(request.user)
            elif action == 'unbookmark':
                customer_record.bookmarked_by.remove(request.user)

            return redirect('record', pk=pk)

        return render(request, 'record.html', {'customer_record': customer_record, 'is_bookmarked': is_bookmarked})
    except Record.DoesNotExist:
        messages.error(request, "The record does not exist.")
        return redirect('home')




def add_record(request):
    if request.user.is_authenticated:
        if request.method == "POST":
            form = AddRecordForm(request.POST)
            if form.is_valid():
                try:
                    record = form.save(commit=False)
                    record.created_by = request.user
                    record.save()
                    messages.success(request, "Record Added...")
                    return redirect('home')
                except ValidationError as e:
                    messages.error(request, str(e))
        else:
            form = AddRecordForm()

        return render(request, 'add_record.html', {'form': form})
    else:
        messages.success(request, "You Must Be Logged In...")
        return redirect('home')



def delete_record(request, pk):
    if request.user.is_authenticated:
        delete_it = Record.objects.get(id=pk)
        delete_it.delete()
        messages.success(request, "Record Deleted Successfully...")
        return redirect('home')
    else:
        messages.success(request, "You Must Be Logged In To Do That...")
        return redirect('home')



def update_record(request, pk):
    if request.user.is_authenticated:
        current_record = Record.objects.get(id=pk)
        form = AddRecordForm(request.POST or None, instance=current_record)
        if form.is_valid():
            form.save()
            messages.success(request, "Record Has Been Updated!")
            return redirect('profile')
        return render(request, 'update_record.html', {'form':form})
    else:
        messages.success(request, "You Must Be Logged In...")
        return redirect('home')


# custom 404 view
def custom_404(request, exception=None):
    return render(request, '404.html', status=404)

def notion_templates(request):
    return render(request, 'notion_templates.html')

def about(request):
    return render(request, 'about.html')

def faq(request):
    return render(request, 'faq.html')

Urls.py

    #password section
    path('password_reset/', auth_views.PasswordResetView.as_view(template_name='password_reset_form.html'), name='password_reset'),
    path('password_reset_done/', auth_views.PasswordResetDoneView.as_view(template_name='password_reset_done.html'), name='password_reset_done'),
    path('password_reset_confirm/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(template_name='password_reset_confirm.html'), name='password_reset_confirm'),
    path('password_reset_complete/', auth_views.PasswordResetCompleteView.as_view(template_name='password_reset_complete.html'), name='password_reset_complete'),

password_reset_form.html:

{% extends 'base.html' %}

{% block content %}

    <h1> Forgot Password</h1>
    <form method = "POST">
        {% csrf_token %}
        {{ form.as_p}}
        <button type="submit">Submit</button>
    </form>

{% endblock %}

password_reset_done.html:

{% extends 'base.html' %}

{% block content %}

<p>
    We've emailed you instructions for setting your password. If an email exists in our records, you should be receiving it shortly.
</p>

<p>
    If you have not recieved an email in our inbox, then check your spam folder, any spelling mistakes, or the correct email associated with us. 
</p>

{% endblock %}

password_reset_confirm.html:

{% extends 'base.html' %}

{% block content %}

    {% if validlink %}
    <h3>Change Password</h3>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Change password</button>
    </form>
    {% else %}
    <p>
        This password link has already been used. Please request a new password link.
    </p>
    {% endif %}
{% endblock %}

password_reset_complete.html:

{% extends 'base.html' %}

{% block content %}

<p>
    Your password has been set. Click here to return to the Login Screen: <a href="{% url 'home' %}"></a>
</p>

{% endblock %}

When I navigate to the password_reset_form.html and enter in verified email it will return the password_reset_confirm.html page. When I navigate to the email, nothing shows. It will return an error if the email isn't verified through aws. (I'm still in sandbox mode I just sent a request to change it to production today.)

If it's these files what am I doing incorrectly?

0

There are 0 best solutions below