ungleich-user/dal/dal/views.py

222 lines
9.6 KiB
Python

from django.shortcuts import render
from django.views.generic import View
from django.contrib.auth import authenticate, login
from django.contrib.auth.models import User
from django.http import HttpResponse, HttpResponseRedirect
from django.core.validators import email_re
from django.urls import reverse_lazy
# Check to see if the username is already taken
# Helper function, not to be set up as a view
def check_user_exists(username):
if User.objects.filter(username=username).exists():
return True
# TODO: Needs to look up the LDAP
else return False
# The index page
# If there's a session open, it will give the user the options he/she/it can do, if not,
# it will show a landing page explaining what this is and prompt them to login
class Index(View):
# Basic binary choice, if it is an authenticated user, go straight to the options page,
# if not, then show the landing page
def get(self, request):
if request.user:
return render(request, 'useroptions.html')
return render(request, 'landing.html')
# Basically does the same as the GET request, just with trying to login the user beforehand
# Shows an errorpage if authentication fails, since just looping to the landing page
# would be frustrating
def post(self, request):
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return render(request, 'useroptions.html')
return render(request, 'loginfailed.html')
# Registering a user
class Register(View):
# Someone wants to register, throw up the page for that
def get(self, request):
return render(request, 'registeruser.html')
# Someone filled out the register page, do some basic checks and throw it at nameko
def post(self, request):
# message for the error template
service = 'Registering an user'
# urlname for 'go back' on the errorpage
urlname = 'register'
# some basic check against DoS, since a hidden reference=ungleich will be given on the registeruser page
# real defense against DoS will not be on django, but this protects a bit against filling up our ldap with a
# basic curl script
# TODO: Think about some better protection
reference = request.POST.get('reference')
if reference != 'ungleich':
return HttpResponseRedirect(reverse_lazy('index'))
username = request.POST.get('username')
# Check to see if username is already taken
if self.check_user_exists(username):
return render(request, 'registererror.html', { 'urlname': urlname, 'service': service, 'error': 'User already exists.' } )
# isalnum() may be a bit harsh, but is the most logical choice to make sure it's a username we
# can use
elif not username.isalnum():
return render(request, 'registererror.html', { 'urlname': urlname, 'service': service, 'error': 'Username has to be alphanumeric.' } )
password1 = request.POST.get('password1')
password2 = request.POST.get('password2')
# check if the supplied passwords match
if password1 != password2:
return render(request, 'registererror.html', { 'urlname': urlname, 'service': service,
'error': 'Your passwords didn\'t match. Please supply the same password twice.' } )
email = request.POST.get('email')
# Is the emailaddress valid?
if not email_re.match(email):
return render(request, 'registererror.html', { 'urlname': urlname, 'service': service, 'error': 'The supplied email address is invalid.' } )
firstname = request.POST.get('firstname')
lastname = request.POST.get('lastname')
if firstname == "" or not firstname or lastname == "" or not lastname
return render(request, 'registererror.html', { 'urlname': urlname, 'service': service, 'error': 'Please enter your firstname and lastname.' } )
# TODO: throw it to nameko to create the user
return render(request, 'usercreated.html', { 'user': username } )
# Change user data for logged in users
class ChangeData(View):
# provide the form for the change request
def get(self, request):
if not request.user.is_authenticated:
return render(request, 'mustbeloggedin.html')
user = request.user
#TODO: nameko get basic data (firstname, lastname, email)
(firstname, lastname, email) = self.get_data(user)
# The template puts the old data as standard in the fields
return render(request, 'changeuserdata.html', { 'user': user, 'firstname': firstname, 'lastname': lastname, 'email': email } )
# get the change request
def post(self, request):
# variables for the error page
service = 'changing user data'
urlname = 'change_data'
if not request.user.is_authenticated:
return render(request, 'mustbeloggedin.html')
user = request.user
firstname = request.POST.get('firstname')
lastname = request.POST.get('lastname')
email = request.POST.get('email')
# Some sanity checks for the supplied data
if firstname == "":
return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': 'Please enter a firstname.' } )
elif lastname == "":
return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': 'Please enter a lastname.' } )
elif email == "":
return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': 'Please enter an email.' } )
elif not email_re.match(email):
return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': 'The supplied email address is invalid.' } )
#TODO: nameko change data (firstname, lastname, email)
if self.change_data(firstname, lastname, email):
return render(request, 'changeddata.html', { 'user': user, 'firstname': firstname, 'lastname': lastname, 'email': email } )
return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': 'An unknown error occurred.' } )
# TODO: call nameko to get basic data from user
def get_data(self, user):
return ("a", "b", "c")
# TODO: call nameko to change user data and think about return value
def change_data(self, firstname, lastname, email):
return True
# Resets the password for a user
# Will need to send a confirmation email to the user and we will need a backend
# to confirm the request came from someone who has access to the email
# Out of scope except for creating the workflow
class ResetPassword(View):
# Presents the form with some information
def get(self, request):
return render(request, 'resetpassword.html')
# gets the data from confirming the reset request and checks if it was not a misclick
# (by having the user type in his username
def post(self, request):
user = request.POST.get('user')
if check_user_exists(user):
#TODO: call nameko for sending a reset request
self.send_resetrequest(user)
return render(request, 'send_resetrequest.html', { 'user': user } )
return render(request, 'must_confirm_reset.html')
def send_resetrequest(self, user):
#TODO: call nameko to get the associated email and send a confirmation mail
return True
# The logged in user can change the password here
class ChangePassword(View):
# Presents the page for a logged in user
def get(self, request):
if not request.user.is_authenticated:
return render(request, 'mustbeloggedin.html')
return render(request, 'changepassword.html', { 'user': request.user } )
# Does some checks on the supplied data and changes the password
def post(self, request):
# Variables for the error page
urlname = 'change_password'
service = 'change the password'
if not request.user.is_authenticated:
return render(request, 'mustbeloggedin.html')
user = request.user
oldpassword = request.POST.get('oldpassword')
check = authenticate(request, username=user, password=oldpassword)
# Is the right password for the user supplied?
if check is None:
return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': 'Wrong password for the user.' } )
password1 = request.POST.get('password1')
password2 = request.POST.get('password2')
# Are both passwords from the form the same?
if password1 != password2:
return render(request, 'error.html', { 'urlname': urlname, 'service': service,
'error': 'Please check if you typed the same password both times for the new password' } )
# TODO: nameko change password
if self.change_password(user, oldpassword, password1):
return render(request, 'changedpassword.html', { 'user': user } )
else:
return render(request, 'error.html', { 'urlname': urlname, 'service': service, 'error': 'Unknown error while changing the password!' } )
# Changes the password for the supplied user
def change_password(self, user, oldpassword, password):
#TODO: write nameko function to change a password
return True
class DeleteAccount(View):
def get(self, request):
return HttpResponse("Work in progress")