1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-19 10:26:17 +00:00

Two factor (#6116)

* update code style

* update remember_me
This commit is contained in:
lian
2024-05-27 09:36:31 +08:00
committed by GitHub
parent 0cd6874296
commit 2e71bc662a

View File

@@ -1,45 +1,32 @@
# Copyright (c) 2012-2016 Seafile Ltd.
import hashlib
import re
import logging
from datetime import datetime
from importlib import import_module
from formtools.wizard.views import SessionWizardView
from constance import config
from django.conf import settings
from django.urls import reverse
from django.http import HttpResponseRedirect, Http404
from django.utils.translation import gettext as _
from django.http import HttpResponseRedirect
from django.views.decorators.cache import never_cache
from django.contrib.sites.shortcuts import get_current_site
from django.shortcuts import redirect
from django.utils.http import url_has_allowed_host_and_scheme
from django.views.decorators.debug import sensitive_post_parameters
from formtools.wizard.views import SessionWizardView
from seahub.auth import REDIRECT_FIELD_NAME, get_backends
from seahub.auth import login as auth_login
from seahub.base.accounts import User
from seahub.utils.ip import get_remote_ip
from seahub.profile.models import Profile
from seahub.two_factor import login as two_factor_login
from seahub.two_factor.models import (StaticDevice, TOTPDevice, default_device,
user_has_device)
from seahub.two_factor.forms import TOTPTokenAuthForm, BackupTokenAuthForm, AuthenticationTokenForm
from seahub.two_factor.models import StaticDevice, default_device, user_has_device
from seahub.two_factor.forms import BackupTokenAuthForm, AuthenticationTokenForm
from seahub.two_factor.views.utils import class_view_decorator
from seahub.utils.auth import get_login_bg_image_path
# Get an instance of a logger
logger = logging.getLogger(__name__)
@class_view_decorator(sensitive_post_parameters())
@class_view_decorator(never_cache)
class TwoFactorVerifyView(SessionWizardView):
@@ -99,28 +86,29 @@ class TwoFactorVerifyView(SessionWizardView):
"""
Login the user and redirect to the desired page.
"""
redirect_to = self.request.session.get(SESSION_KEY_TWO_FACTOR_REDIRECT_URL, '') \
or self.request.GET.get(self.redirect_field_name, '')
redirect_to = (
self.request.session.get(SESSION_KEY_TWO_FACTOR_REDIRECT_URL, '')
or self.request.GET.get(self.redirect_field_name, '')
)
auth_login(self.request, self.user)
self.reset_two_factor_session()
if not url_has_allowed_host_and_scheme(url=redirect_to, allowed_hosts=self.request.get_host()):
if not url_has_allowed_host_and_scheme(url=redirect_to,
allowed_hosts=self.request.get_host()):
redirect_to = str(settings.LOGIN_REDIRECT_URL)
res = HttpResponseRedirect(redirect_to)
if form_list[0].is_valid():
remember_me = form_list[0].cleaned_data['remember_me']
if remember_me:
s = remember_device(self.user.username)
res.set_cookie(
'S2FA', s.session_key,
max_age=settings.TWO_FACTOR_DEVICE_REMEMBER_DAYS * 24 * 60 * 60,
domain=settings.SESSION_COOKIE_DOMAIN,
path=settings.SESSION_COOKIE_PATH,
secure=settings.SESSION_COOKIE_SECURE or None,
httponly=settings.SESSION_COOKIE_HTTPONLY or None)
if kwargs.get('remember_me', False):
s = remember_device(self.user.username)
res.set_cookie(
'S2FA', s.session_key,
max_age=settings.TWO_FACTOR_DEVICE_REMEMBER_DAYS * 24 * 60 * 60,
domain=settings.SESSION_COOKIE_DOMAIN,
path=settings.SESSION_COOKIE_PATH,
secure=settings.SESSION_COOKIE_SECURE or None,
httponly=settings.SESSION_COOKIE_HTTPONLY or None)
return res
def get_form_kwargs(self, step=None):
@@ -199,22 +187,28 @@ class TwoFactorVerifyView(SessionWizardView):
)
final_form_list.append(form_obj)
kwargs['remember_me'] = form.cleaned_data['remember_me']
done_response = self.done(final_form_list, **kwargs)
self.storage.reset()
return done_response
def two_factor_auth_enabled(user):
return config.ENABLE_TWO_FACTOR_AUTH and user_has_device(user)
SESSION_KEY_TWO_FACTOR_AUTH_USERNAME = '2fa-username'
SESSION_KEY_TWO_FACTOR_REDIRECT_URL = '2fa-redirect-url'
SESSION_KEY_TWO_FACTOR_FAILED_ATTEMPT = '2fa-failed-attempt'
def handle_two_factor_auth(request, user, redirect_to):
request.session[SESSION_KEY_TWO_FACTOR_AUTH_USERNAME] = user.username
request.session[SESSION_KEY_TWO_FACTOR_REDIRECT_URL] = redirect_to
request.session[SESSION_KEY_TWO_FACTOR_FAILED_ATTEMPT] = 0
return redirect(reverse('two_factor_auth'))
def verify_two_factor_token(user, token):
"""
This function is called when doing the api authentication.
@@ -225,6 +219,7 @@ def verify_two_factor_token(user, token):
if device:
return device.verify_token(token)
def remember_device(s_data):
SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
s = SessionStore()
@@ -233,6 +228,7 @@ def remember_device(s_data):
s.create()
return s
def is_device_remembered(request_header, user):
if not request_header:
return False