1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-30 21:50:59 +00:00

Merge branch 'master' into 12.0

This commit is contained in:
杨顺强 2024-05-27 10:39:14 +08:00
commit d24d71420e
5 changed files with 43 additions and 40 deletions

View File

@ -14,7 +14,7 @@
"@gatsbyjs/reach-router": "1.3.9",
"@seafile/react-image-lightbox": "2.0.2",
"@seafile/resumablejs": "1.1.16",
"@seafile/sdoc-editor": "0.5.63",
"@seafile/sdoc-editor": "0.5.64",
"@seafile/seafile-calendar": "0.0.12",
"@seafile/seafile-editor": "1.0.82",
"@uiw/codemirror-extensions-langs": "^4.19.4",
@ -4617,9 +4617,9 @@
"integrity": "sha512-8rBbmAEuuwOAGHYGCtEzpx+bxAcGS+V30otMmhRe7bPAdh4E57RWgCa8x7pkzHGFlY1t5d+ILz1gojvPVMYQig=="
},
"node_modules/@seafile/sdoc-editor": {
"version": "0.5.63",
"resolved": "https://registry.npmjs.org/@seafile/sdoc-editor/-/sdoc-editor-0.5.63.tgz",
"integrity": "sha512-qXi1VOSSfREtsVwdVSj7brLhsqIc7+rxBX8WHQlioUmSvv53xd/RBFJRtmla9Ui+LvmyCSGtzZ4oTKZU2/WAGA==",
"version": "0.5.64",
"resolved": "https://registry.npmjs.org/@seafile/sdoc-editor/-/sdoc-editor-0.5.64.tgz",
"integrity": "sha512-kDZwJEprBvvo8qCsaEh4zoPJLsKkg5d9co20buJ20raMDTd3IH/iuylj4Pp3hEyiSUFeT4zwOdxMFV2Vr1a+UQ==",
"dependencies": {
"@seafile/print-js": "1.6.5",
"@seafile/react-image-lightbox": "2.0.4",
@ -31292,9 +31292,9 @@
"integrity": "sha512-8rBbmAEuuwOAGHYGCtEzpx+bxAcGS+V30otMmhRe7bPAdh4E57RWgCa8x7pkzHGFlY1t5d+ILz1gojvPVMYQig=="
},
"@seafile/sdoc-editor": {
"version": "0.5.63",
"resolved": "https://registry.npmjs.org/@seafile/sdoc-editor/-/sdoc-editor-0.5.63.tgz",
"integrity": "sha512-qXi1VOSSfREtsVwdVSj7brLhsqIc7+rxBX8WHQlioUmSvv53xd/RBFJRtmla9Ui+LvmyCSGtzZ4oTKZU2/WAGA==",
"version": "0.5.64",
"resolved": "https://registry.npmjs.org/@seafile/sdoc-editor/-/sdoc-editor-0.5.64.tgz",
"integrity": "sha512-kDZwJEprBvvo8qCsaEh4zoPJLsKkg5d9co20buJ20raMDTd3IH/iuylj4Pp3hEyiSUFeT4zwOdxMFV2Vr1a+UQ==",
"requires": {
"@seafile/print-js": "1.6.5",
"@seafile/react-image-lightbox": "2.0.4",

View File

@ -9,7 +9,7 @@
"@gatsbyjs/reach-router": "1.3.9",
"@seafile/react-image-lightbox": "2.0.2",
"@seafile/resumablejs": "1.1.16",
"@seafile/sdoc-editor": "0.5.63",
"@seafile/sdoc-editor": "0.5.64",
"@seafile/seafile-calendar": "0.0.12",
"@seafile/seafile-editor": "1.0.82",
"@uiw/codemirror-extensions-langs": "^4.19.4",

View File

@ -29,6 +29,7 @@ from saml2.client import Saml2Client
from saml2.metadata import entity_descriptor
from djangosaml2.cache import IdentityCache, OutstandingQueriesCache
from djangosaml2.conf import get_config
from djangosaml2.views import LogoutView
from seaserv import ccnet_api, seafile_api
@ -562,3 +563,7 @@ def adfs_compatible_view(request, url_prefix):
org_id = str(org.org_id)
return HttpResponsePermanentRedirect(request.path.replace(url_prefix, org_id))
class SamlLogoutView(LogoutView):
def do_logout_service(self, request, data, binding, *args, **kwargs):
return super(SamlLogoutView, self).do_logout_service(request, data, binding)

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

View File

@ -942,6 +942,8 @@ if getattr(settings, 'ENABLE_MULTI_ADFS', False):
re_path(r'^org/custom/(?P<org_id>\d+)/saml2/metadata/$', metadata, name='org_saml2_metadata'),
re_path(r'^org/custom/(?P<org_id>\d+)/saml2/connect/$', saml2_connect, name='org_saml2_connect'),
re_path(r'^org/custom/(?P<org_id>\d+)/saml2/disconnect/$', saml2_disconnect, name='org_saml2_disconnect'),
re_path(r'^org/custom/(?P<org_id>\d+)/saml2/ls/$', SamlLogoutView.as_view(), name='org_saml2_ls'),
re_path(r'^org/custom/(?P<org_id>\d+)/saml2/ls/post/$', SamlLogoutView.as_view(), name='org_saml2_ls_post'),
re_path(r'^org/custom/(?P<org_id>\d+)/saml2/', include(('djangosaml2.urls', 'djangosaml2'), namespace='org')),
re_path(r'^org/custom/(?P<url_prefix>[a-z_0-9-]+)/saml2/login/$', adfs_compatible_view, name='login_compatible_view'),
re_path(r'^org/custom/(?P<url_prefix>[a-z_0-9-]+)/saml2/acs/$', adfs_compatible_view, name='acs_compatible_view'),