added email verification to signup

This commit is contained in:
iou1name 2019-01-21 15:59:31 -05:00
parent ee7eaeabc0
commit 5bba661208
10 changed files with 117 additions and 4 deletions

View File

@ -12,7 +12,6 @@ from django.shortcuts import render, redirect
from django.db.models import F from django.db.models import F
from django.conf import settings from django.conf import settings
from django.urls import reverse from django.urls import reverse
from django.http import HttpResponse
from .models import Quest, DiceRoll, PollOption, PollVote, Page, Post from .models import Quest, DiceRoll, PollOption, PollVote, Page, Post
from .forms import EditQuestForm, QuestForm, PostForm from .forms import EditQuestForm, QuestForm, PostForm

View File

@ -0,0 +1,5 @@
{% extends "base.html" %}
{% block title %}Email confirmation sent{% endblock %}
{% block content %}
A confirmation email has been sent to {{ user.email }}. Please follow the enclosed instructions to finish creating your account. Be sure to check your spam folder if you do not see the email.
{% endblock %}

View File

@ -0,0 +1,6 @@
{% extends "base.html" %}
{% block title %}Success!{% endblock %}
{% block content %}
Your account has been activated. You may now <a href="{{ url('login:index') }}">login</a>.
{% endblock %}

17
signup/models.py Normal file
View File

@ -0,0 +1,17 @@
#!/usr/bin/env python3
"""
A table to lookup confirmation codes.
"""
from django.db import models
from django.conf import settings
class Confirmation(models.Model):
"""
Contains a reference to the user's newly created account
and a random string to be emailed to them for them to confirm.
"""
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
code = models.CharField(max_length=32)

View File

@ -9,4 +9,5 @@ from . import views
app_name = 'signup' app_name = 'signup'
urlpatterns = [ urlpatterns = [
path('', views.index, name='index'), path('', views.index, name='index'),
path('verify', views.verify, name='verify'),
] ]

View File

@ -3,9 +3,16 @@
/signup app views. /signup app views.
""" """
# TODO: make unique username validation be case insensitive # TODO: make unique username validation be case insensitive
import random
import string
from django.shortcuts import redirect, render from django.shortcuts import redirect, render
from django.core.mail import send_mail
from django.urls import reverse
from django.conf import settings
from .forms import SignupForm from .forms import SignupForm
from .models import Confirmation
def index(request): def index(request):
""" """
@ -16,8 +23,58 @@ def index(request):
if request.method == 'POST': if request.method == 'POST':
form = SignupForm(request.POST) form = SignupForm(request.POST)
if form.is_valid(): if form.is_valid():
form.save() user = form.save()
return redirect('login:index') confirm = Confirmation(
user=user,
code=get_code(32)
)
confirm.save()
verify_url = request.build_absolute_uri(reverse('signup:verify'))
verify_url = verify_url.replace("http", "https")
email_confirmation(confirm, verify_url)
return render(request, 'signup/confirmation_sent.html', locals())
else: else:
form = SignupForm() form = SignupForm()
return render(request, 'signup/index.html', {'form': form}) return render(request, 'signup/index.html', {'form': form})
def get_code(n):
"""
Helper function to generate n number of psudeo-random ASCII characters.
"""
chars = []
for _ in range(n):
chars.append(random.choice(string.ascii_letters + string.digits))
return "".join(chars)
def email_confirmation(confirm, verify_url):
"""
Sends out a confirmation to the user.
"""
message = "Please use the following link to verify your account: "
message += verify_url + "?code=" + confirm.code
send_mail(
"Email verification",
message,
settings.DEFAULT_FROM_EMAIL,
[confirm.user.email],
)
def verify(request):
"""
Verifies and activates the user's account.
"""
code = request.GET.get("code")
if not code:
return redirect('homepage:index')
try:
confirm = Confirmation.objects.get(code=code)
except Confirmation.DoesNotExist:
return redirect('homepage:index')
user = confirm.user
user.is_active = True
user.save()
confirm.delete()
return render(request, 'signup/confirmed.html', locals())

View File

@ -168,3 +168,11 @@ TAGGIT_CASE_INSENSITIVE = True
# Server user id # Server user id
SERVER_USER_ID = 3 SERVER_USER_ID = 3
DEFAULT_FROM_EMAIL = "scribe@steelbea.me"
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = "mail.steelbea.me"
EMAIL_HOST_PASSWORD = titivillus.settings_secret.EMAIL_KEY
EMAIL_HOST_USER = "scribe@steelbea.me"
EMAIL_PORT = 587
EMAIL_USE_TLS = True

3
todo
View File

@ -1,5 +1,4 @@
New Features: New Features:
Notifications
Front page to show new quests Front page to show new quests
Webm posting Webm posting
(you) counter (you) counter
@ -15,3 +14,5 @@ Total voters per poll
Chat archives Chat archives
Adjust quote preview postioning Adjust quote preview postioning
Better API Better API
Reserve/prevent certain usernames eg. Admin, Administrator, etc.
Search from front page doesn't work

View File

@ -0,0 +1,18 @@
# Generated by Django 2.1.1 on 2019-01-18 17:51
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('user', '0003_user_subscriptions'),
]
operations = [
migrations.AlterField(
model_name='user',
name='is_active',
field=models.BooleanField(default=False),
),
]

View File

@ -47,6 +47,7 @@ class User(AbstractUser):
+ "the conversation." + "the conversation."
) )
subscriptions = models.ManyToManyField(Quest) subscriptions = models.ManyToManyField(Quest)
is_active = models.BooleanField(default=False)
def get_full_name(self): def get_full_name(self):
return None return None