You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

182 lines
5.3 KiB

import uuid
from django.contrib import messages
from django.contrib.auth import login as auth_login
from django.contrib.auth import logout as auth_logout
from django.contrib.auth import authenticate
from django.contrib.auth.decorators import login_required
from django.contrib.auth.hashers import check_password
from django.contrib.auth.models import User
from django.core import signing
from django.http import HttpResponseBadRequest
from django.shortcuts import redirect, render
from hc.accounts.forms import (EmailPasswordForm, ReportSettingsForm,
SetPasswordForm)
from hc.accounts.models import Profile
from hc.api.models import Channel, Check
def _make_user(email):
username = str(uuid.uuid4())[:30]
user = User(username=username, email=email)
user.set_unusable_password()
user.save()
channel = Channel()
channel.user = user
channel.kind = "email"
channel.value = email
channel.email_verified = True
channel.save()
return user
def _associate_demo_check(request, user):
if "welcome_code" in request.session:
check = Check.objects.get(code=request.session["welcome_code"])
# Only associate demo check if it doesn't have an owner already.
if check.user is None:
check.user = user
check.save()
check.assign_all_channels()
del request.session["welcome_code"]
def login(request):
bad_credentials = False
if request.method == 'POST':
form = EmailPasswordForm(request.POST)
if form.is_valid():
email = form.cleaned_data["email"]
password = form.cleaned_data["password"]
if len(password):
user = authenticate(username=email, password=password)
if user is not None and user.is_active:
auth_login(request, user)
return redirect("hc-checks")
bad_credentials = True
else:
try:
user = User.objects.get(email=email)
except User.DoesNotExist:
user = _make_user(email)
_associate_demo_check(request, user)
profile = Profile.objects.for_user(user)
profile.send_instant_login_link()
return redirect("hc-login-link-sent")
else:
form = EmailPasswordForm()
bad_link = request.session.pop("bad_link", None)
ctx = {
"form": form,
"bad_credentials": bad_credentials,
"bad_link": bad_link
}
return render(request, "accounts/login.html", ctx)
def logout(request):
auth_logout(request)
return redirect("hc-index")
def login_link_sent(request):
return render(request, "accounts/login_link_sent.html")
def set_password_link_sent(request):
return render(request, "accounts/set_password_link_sent.html")
def check_token(request, username, token):
if request.user.is_authenticated() and request.user.username == username:
# User is already logged in
return redirect("hc-checks")
user = authenticate(username=username, token=token)
if user is not None and user.is_active:
# This should get rid of "welcome_code" in session
request.session.flush()
profile = Profile.objects.for_user(user)
profile.token = ""
profile.save()
auth_login(request, user)
return redirect("hc-checks")
request.session["bad_link"] = True
return redirect("hc-login")
@login_required
def profile(request):
profile = Profile.objects.for_user(request.user)
if request.method == "POST":
if "set_password" in request.POST:
profile.send_set_password_link()
return redirect("hc-set-password-link-sent")
form = ReportSettingsForm(request.POST)
if form.is_valid():
profile.reports_allowed = form.cleaned_data["reports_allowed"]
profile.save()
messages.info(request, "Your settings have been updated!")
ctx = {
"profile": profile
}
return render(request, "accounts/profile.html", ctx)
@login_required
def set_password(request, token):
profile = Profile.objects.for_user(request.user)
if not check_password(token, profile.token):
return HttpResponseBadRequest()
if request.method == "POST":
form = SetPasswordForm(request.POST)
if form.is_valid():
password = form.cleaned_data["password"]
request.user.set_password(password)
request.user.save()
profile.token = ""
profile.save()
# Setting a password logs the user out, so here we
# log them back in.
u = authenticate(username=request.user.email, password=password)
auth_login(request, u)
messages.info(request, "Your password has been set!")
return redirect("hc-profile")
ctx = {
}
return render(request, "accounts/set_password.html", ctx)
def unsubscribe_reports(request, username):
try:
signing.Signer().unsign(request.GET.get("token"))
except signing.BadSignature:
return HttpResponseBadRequest()
user = User.objects.get(username=username)
profile = Profile.objects.for_user(user)
profile.reports_allowed = False
profile.save()
return render(request, "accounts/unsubscribed.html")