Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ services:
/usr/bin/mc anonymous set download minio_docker/$AWS_STORAGE_BUCKET_NAME;
else
echo 'MINIO_ACCESS_KEY, MINIO_SECRET_KEY, or MINIO_PORT are not defined. Skipping buckets creation.';
fi
fi;
exit 0;
"

Expand Down
6 changes: 5 additions & 1 deletion src/apps/profiles/urls_accounts.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.conf.urls import url
from django.urls import path

from . import views
from django.contrib.auth import views as auth_views

app_name = "accounts"

Expand All @@ -12,4 +12,8 @@
path('login/', views.LoginView.as_view(), name='login'),
# path('logout/', auth_views.LogoutView.as_view(), name='logout'),
path('logout/', views.LogoutView.as_view(), name='logout'),
path('password_reset/', views.CustomPasswordResetView.as_view(), name='password_reset'),
path('password_reset/done/', auth_views.PasswordResetDoneView.as_view(), name='password_reset_done'),
path('reset/<uidb64>/<token>/', views.CustomPasswordResetConfirmView.as_view(), name='password_reset_confirm'),
path('reset/done/', auth_views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
]
75 changes: 74 additions & 1 deletion src/apps/profiles/views.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import json
import django

from django.conf import settings
from django.contrib import messages
from django.contrib.auth import authenticate
from django.contrib.sites.shortcuts import get_current_site
from django.core.mail import EmailMessage
from django.core.mail import EmailMessage, EmailMultiAlternatives
from django.http import Http404
from django.shortcuts import render, redirect
from django.contrib.auth import views as auth_views
from django.contrib.auth import forms as auth_forms
from django.contrib.auth.mixins import LoginRequiredMixin
from django.template.loader import render_to_string
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
Expand Down Expand Up @@ -126,6 +128,77 @@ def sign_up(request):
return render(request, 'registration/signup.html', context)


# Password Reset views/forms below
# auth_forms
class CustomPasswordResetForm(auth_forms.PasswordResetForm):
"""
Subclassed auth_forms.PasswordResetForm in order to add a print statement
to see the email in the logs.
Source: https://github.com/django/django/blob/8b1ff0da4b162e87edebd94e61f2cd153e9e159d/django/contrib/auth/forms.py#L287
"""
def send_mail(
self,
subject_template_name,
email_template_name,
context,
from_email,
to_email,
html_email_template_name=None,
):
"""
Send a django.core.mail.EmailMultiAlternatives to `to_email`.
"""
subject = render_to_string(subject_template_name, context)
# Email subject *must not* contain newlines
subject = "".join(subject.splitlines())
body = render_to_string(email_template_name, context)

email_message = EmailMultiAlternatives(subject, body, from_email, [to_email])
print(email_message.message())
if html_email_template_name is not None:
html_email = render_to_string(html_email_template_name, context)
email_message.attach_alternative(html_email, "text/html")

email_message.send()


# auth_views
# https://devdocs.io/django~2.2/topics/auth/default#django.contrib.auth.views.PasswordChangeView # Search for PasswordResetView
class CustomPasswordResetView(auth_views.PasswordResetView):
"""
1. form_class: subclassing auth_views.PasswordResetView to use a custom form "CustomPasswordResetForm" above
2. success_url: Our src/apps/profiles/urls_accounts.py has become an "app" with the use of "app_name".
We have to use app:view_name syntax in templates like " {% url 'accounts:password_reset_confirm'%} "
Therefore we need to tell this view to find the right success_url with that syntax or django won't be
able to find the view.
3. from_email: We want to set the from_email to info@codalab.org - may eventually put in .env file.
# The other commented sections are the defaults for other attributes in auth_views.PasswordResetView.
They are in here in case someone wants to customize in the future. All attributes show up in the order
shown in the docs.
"""
# template_name = 'registration/password_reset_form.html'
form_class = CustomPasswordResetForm # auth_forms.PasswordResetForm
# email_template_name = '' # Defaults to registration/password_reset_email.html if not supplied.
# subject_template_name = '' # Defaults to registration/password_reset_subject.txt if not supplied.
# token_generator = '' # This will default to default_token_generator, it’s an instance of django.contrib.auth.tokens.PasswordResetTokenGenerator.
success_url = django.urls.reverse_lazy("accounts:password_reset_done")
from_email = "info@codalab.org"


class CustomPasswordResetConfirmView(auth_views.PasswordResetConfirmView):
"""
1. success_url: Our src/apps/profiles/urls_accounts.py has become an "app" with the use of "app_name".
We have to use app:view_name syntax in templates like " {% url 'accounts:password_reset_confirm'%} "
Therefore we need to tell this view to find the right success_url with that syntax or django won't be
able to find the view.
"""
# template_name = '' # Default value is registration/password_reset_confirm.html.
# form_class = '' # Defaults to django.contrib.auth.forms.SetPasswordForm.
# token_generator = '' # This will default to default_token_generator, it’s an instance of django.contrib.auth.tokens.PasswordResetTokenGenerator.
# post_reset_login = '' # Defaults to False.
success_url = django.urls.reverse_lazy("accounts:password_reset_complete")


class UserNotificationEdit(LoginRequiredMixin, DetailView):
queryset = User.objects.all()
template_name = 'profiles/user_notifications.html'
Expand Down
4 changes: 4 additions & 0 deletions src/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@
</i><i class="bell icon"></i>
Notifications
</a>
<a class="item" href="{% url 'accounts:password_reset' %}">
<i class="icon sign out"></i>
Change Password
</a>
<a class="item" href="{% url 'accounts:logout' %}">
<i class="icon sign out"></i>
Logout
Expand Down
1 change: 1 addition & 0 deletions src/templates/registration/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ <h2 class="ui blue centered header">
<button class="ui fluid blue submit button" type="submit">Log In</button>
<div class="ui divider"></div>
<p>New to us? <a href="{% url 'accounts:signup' %}">Sign Up</a></p>
<p><a href="{% url 'accounts:password_reset' %}">Forgot your password?</a></p>

<div class="ui error message"></div>
</form>
Expand Down
10 changes: 10 additions & 0 deletions src/templates/registration/password_reset_complete.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{% extends 'base.html' %}

{% block content %}
<div class="six wide centered column">
<h2 class="ui blue header">
Password Reset Complete
</h2>
<p>Your password has been successfully reset.</p>
</div>
{% endblock %}
14 changes: 14 additions & 0 deletions src/templates/registration/password_reset_confirm.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{% extends 'base.html' %}

{% block content %}
<div class="six wide centered column">
<h2 class="ui blue header">
Change Password
</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Reset Password</button>
</form>
</div>
{% endblock %}
18 changes: 18 additions & 0 deletions src/templates/registration/password_reset_done.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{% extends "registration/registration_base.html" %}

{% block title %}Password reset{% endblock %}

{% block content %}
<div class="six wide centered column">
<h2 class="ui blue header">
Password Reset Complete
</h2>
<p>
We have sent you an email with a link to reset your password. Please check
your email and click the link to continue.
</p>
</div>
{% endblock %}


{# This is used by django.contrib.auth #}
2 changes: 2 additions & 0 deletions src/templates/registration/password_reset_email.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Someone asked for password reset for email {{ email }}. Follow the link below:
{{ protocol}}://{{ domain }}{% url 'accounts:password_reset_confirm' uidb64=uid token=token %}
24 changes: 24 additions & 0 deletions src/templates/registration/password_reset_form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{% extends "registration/registration_base.html" %}


{% block title %}Reset password{% endblock %}

{% block content %}
<div class="six wide centered column">
<h2 class="ui blue header">
Reset password
</h2>
{% if user.is_authenticated %}
<p><strong>Note:</strong> you are already logged in as {{ user.username }}.</p>
{% endif %}
<p>Forgot your password? Enter your email in the form below and we'll send you instructions for creating a new one.</p>
<form method="post" action="">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Reset password" />
</form>
</div>
{% endblock %}


{# This is used by django.contrib.auth #}
1 change: 1 addition & 0 deletions src/templates/registration/registration_base.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% extends "base.html" %}