diff --git a/seahub/auth/views.py b/seahub/auth/views.py index 996f13bbfe..fabb7a3e6b 100644 --- a/seahub/auth/views.py +++ b/seahub/auth/views.py @@ -1,6 +1,7 @@ # Copyright (c) 2012-2016 Seafile Ltd. import hashlib import logging +import jwt from datetime import datetime from django.conf import settings # Avoid shadowing the login() view below. @@ -17,7 +18,7 @@ from django.utils.translation import gettext as _ from django.views.decorators.cache import never_cache from saml2.ident import decode from seaserv import seafile_api, ccnet_api - +from seahub.settings import SSO_SECRET_KEY from seahub.auth import REDIRECT_FIELD_NAME, get_backends from seahub.auth import login as auth_login from seahub.auth.models import SocialAuthUser @@ -215,42 +216,43 @@ def login(request, template_name='registration/login.html', }) def login_simple_check(request): - """A simple check for login called by thirdpart systems(OA, etc). - Token generation: MD5(secret_key + foo@foo.com + 2014-1-1).hexdigest() - Token length: 32 hexadecimal digits. - """ - username = request.GET.get('user', '') - random_key = request.GET.get('token', '') + if not SSO_SECRET_KEY: + return render_error(request, 'Permission denied.') + + login_token = request.GET.get('token', '') + if not login_token: + return render_error(request, 'token invalid.') - if not username or not random_key: - raise Http404 + try: + payload = jwt.decode(login_token, SSO_SECRET_KEY, algorithms=['HS256']) + except jwt.ExpiredSignatureError: + return render_error(request, 'token expired.') + except jwt.PyJWTError: + return render_error(request, 'token invalid.') - today = datetime.now().strftime('%Y-%m-%d') - expect = hashlib.md5((settings.SECRET_KEY+username+today).encode('utf-8')).hexdigest() - if expect == random_key: - try: - user = User.objects.get(email=username) - except User.DoesNotExist: - raise Http404 - - for backend in get_backends(): - user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__) - - auth_login(request, user) - - # Ensure the user-originating redirection url is safe. - if REDIRECT_FIELD_NAME in request.GET: - next_page = request.GET[REDIRECT_FIELD_NAME] - if not url_has_allowed_host_and_scheme(url=next_page, allowed_hosts=request.get_host()): - next_page = settings.LOGIN_REDIRECT_URL - else: - next_page = settings.SITE_ROOT - - return HttpResponseRedirect(next_page) + if 'exp' not in payload: + return render_error(request, 'token invalid.') + + user_id = payload.get('user_id') + if not user_id: + return render_error(request, 'token invalid.') + + try: + user = User.objects.get(email=user_id) + except User.DoesNotExist: + return render_error(request, 'token invalid.') + + for backend in get_backends(): + user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__) + auth_login(request, user) + if REDIRECT_FIELD_NAME in request.GET: + next_page = request.GET[REDIRECT_FIELD_NAME] + if not url_has_allowed_host_and_scheme(url=next_page, allowed_hosts=request.get_host()): + next_page = settings.LOGIN_REDIRECT_URL else: - raise Http404 - + next_page = settings.SITE_ROOT + return HttpResponseRedirect(next_page) def logout(request, next_page=None, template_name='registration/logged_out.html', diff --git a/seahub/settings.py b/seahub/settings.py index 20818c9856..98541d8e95 100644 --- a/seahub/settings.py +++ b/seahub/settings.py @@ -767,6 +767,9 @@ ENABLE_SSO_TO_THIRDPART_WEBSITE = False THIRDPART_WEBSITE_SECRET_KEY = '' THIRDPART_WEBSITE_URL = '' + +SSO_SECRET_KEY = '' + # client sso CLIENT_SSO_VIA_LOCAL_BROWSER = False CLIENT_SSO_TOKEN_EXPIRATION = 5 * 60 diff --git a/seahub/urls.py b/seahub/urls.py index 60199780b5..804ecf95d8 100644 --- a/seahub/urls.py +++ b/seahub/urls.py @@ -6,7 +6,7 @@ from seahub.ai.apis import ImageCaption, GenerateSummary from seahub.api2.endpoints.share_link_auth import ShareLinkUserAuthView, ShareLinkEmailAuthView from seahub.api2.endpoints.internal_api import InternalUserListView, InternalCheckShareLinkAccess, \ InternalCheckFileOperationAccess -from seahub.auth.views import multi_adfs_sso +from seahub.auth.views import multi_adfs_sso, login_simple_check from seahub.views import * from seahub.views.mobile import mobile_login from seahub.views.sysadmin import * @@ -950,6 +950,12 @@ if getattr(settings, 'ENABLE_KRB5_LOGIN', False): urlpatterns += [ re_path(r'^krb5-login/', shib_login, name="krb5_login"), ] + + +if getattr(settings, 'ENABLE_LOGIN_SIMPLE_CHECK', False): + urlpatterns += [ + re_path(r'^sso-auto-login/', login_simple_check), + ] # serve office converter static files from seahub.utils import HAS_OFFICE_CONVERTER diff --git a/thirdpart/registration/auth_urls.py b/thirdpart/registration/auth_urls.py index 5fc9c44dc0..1cb322d80c 100644 --- a/thirdpart/registration/auth_urls.py +++ b/thirdpart/registration/auth_urls.py @@ -54,13 +54,6 @@ urlpatterns = [ name='two_factor_auth'), ] -if getattr(settings, 'ENABLE_LOGIN_SIMPLE_CHECK', False): - urlpatterns += [ - path('login/simple_check/', - auth_views.login_simple_check), - ] - - urlpatterns += [ path('login/', auth_views.login,