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")
|