improve one time login security
This commit is contained in:
parent
f968642578
commit
43dbd24dd4
2 changed files with 14 additions and 12 deletions
|
|
@ -10,7 +10,7 @@ from django.contrib import messages
|
||||||
from repapp.models import Organisator, Reparateur, OneTimeLogin
|
from repapp.models import Organisator, Reparateur, OneTimeLogin
|
||||||
|
|
||||||
|
|
||||||
def create_one_time_login(user, url):
|
def create_one_time_login(user, url) -> str:
|
||||||
"""
|
"""
|
||||||
create_one_time_login create a one time login object for user logins.
|
create_one_time_login create a one time login object for user logins.
|
||||||
"""
|
"""
|
||||||
|
|
@ -18,18 +18,19 @@ def create_one_time_login(user, url):
|
||||||
f'{user.email}{url}{datetime.datetime.now()}{random.randint(0,9999999)}'.encode(
|
f'{user.email}{url}{datetime.datetime.now()}{random.randint(0,9999999)}'.encode(
|
||||||
'utf-8')
|
'utf-8')
|
||||||
).hexdigest()
|
).hexdigest()
|
||||||
|
hash = sha256(secret.encode('utf-8')).hexdigest()
|
||||||
otl = OneTimeLogin(
|
otl = OneTimeLogin(
|
||||||
secret=secret,
|
secret=hash,
|
||||||
user=user,
|
user=user,
|
||||||
url=url,
|
url=url,
|
||||||
)
|
)
|
||||||
otl.save()
|
otl.save()
|
||||||
return otl
|
return secret
|
||||||
|
|
||||||
|
|
||||||
def send_one_time_login_mail(one_time_login, request):
|
def send_one_time_login_mail(secret, mail, request):
|
||||||
url = request.build_absolute_uri(
|
url = request.build_absolute_uri(
|
||||||
f'/onetimelogin/{one_time_login.secret}/')
|
f'/onetimelogin/{secret}/')
|
||||||
subject = render_to_string(
|
subject = render_to_string(
|
||||||
'repapp/mail/mail_one_time_login_subject.html').replace('\n', '')
|
'repapp/mail/mail_one_time_login_subject.html').replace('\n', '')
|
||||||
text = render_to_string('repapp/mail/mail_one_time_login_text.html', {
|
text = render_to_string('repapp/mail/mail_one_time_login_text.html', {
|
||||||
|
|
@ -43,7 +44,7 @@ def send_one_time_login_mail(one_time_login, request):
|
||||||
subject=subject,
|
subject=subject,
|
||||||
message=text,
|
message=text,
|
||||||
from_email=os.getenv("DJANGO_SENDER_ADDRESS", ""),
|
from_email=os.getenv("DJANGO_SENDER_ADDRESS", ""),
|
||||||
recipient_list=[f"{one_time_login.user.email}"],
|
recipient_list=[mail],
|
||||||
fail_silently=True,
|
fail_silently=True,
|
||||||
html_message=html
|
html_message=html
|
||||||
)
|
)
|
||||||
|
|
@ -100,8 +101,8 @@ def send_confirmation_mails(device, guest, cafe, request):
|
||||||
path = reverse('view_device', kwargs={
|
path = reverse('view_device', kwargs={
|
||||||
'device_identifier': device.identifier})
|
'device_identifier': device.identifier})
|
||||||
url = request.build_absolute_uri(path)
|
url = request.build_absolute_uri(path)
|
||||||
otl = create_one_time_login(guest.user, url)
|
secret = create_one_time_login(guest.user, url)
|
||||||
login_url = request.build_absolute_uri(f'/onetimelogin/{otl.secret}/')
|
login_url = request.build_absolute_uri(f'/onetimelogin/{secret}/')
|
||||||
|
|
||||||
subject = render_to_string('repapp/mail/mail_register_device_subject.html', {
|
subject = render_to_string('repapp/mail/mail_register_device_subject.html', {
|
||||||
'cafe': cafe,
|
'cafe': cafe,
|
||||||
|
|
|
||||||
|
|
@ -258,20 +258,21 @@ def process_mails(request):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def one_time_login(request, secret):
|
def one_time_login(request, secret: str):
|
||||||
"""
|
"""
|
||||||
View for one time login.
|
View for one time login.
|
||||||
"""
|
"""
|
||||||
# waste a little time as brute force protection
|
# waste a little time as brute force protection
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
otl = get_object_or_404(OneTimeLogin, secret=secret)
|
hash = sha256(secret.encode('utf-8')).hexdigest()
|
||||||
|
otl = get_object_or_404(OneTimeLogin, secret=hash)
|
||||||
|
|
||||||
if otl.login_used:
|
if otl.login_used:
|
||||||
messages.add_message(request, messages.ERROR,
|
messages.add_message(request, messages.ERROR,
|
||||||
'Der Einmal-Login wurde schon verwendet und ist nichtmehr gültig.')
|
'Der Einmal-Login wurde schon verwendet und ist nichtmehr gültig.')
|
||||||
new_otl = create_one_time_login(otl.user, otl.url)
|
secret = create_one_time_login(otl.user, otl.url)
|
||||||
send_one_time_login_mail(new_otl, request)
|
send_one_time_login_mail(secret, otl.user.email, request)
|
||||||
return HttpResponseRedirect(reverse_lazy('index'))
|
return HttpResponseRedirect(reverse_lazy('index'))
|
||||||
else:
|
else:
|
||||||
otl.login_used = True
|
otl.login_used = True
|
||||||
|
|
|
||||||
Reference in a new issue