mirror of
https://github.com/haiwen/seahub.git
synced 2025-08-17 14:37:58 +00:00
132 lines
5.5 KiB
Python
132 lines
5.5 KiB
Python
|
from django.conf import settings
|
||
|
from django.contrib.auth import REDIRECT_FIELD_NAME
|
||
|
from django.contrib.auth.decorators import login_required
|
||
|
from django.views.decorators.csrf import csrf_exempt, csrf_protect
|
||
|
from django.views.decorators.http import require_POST
|
||
|
from django.views.decorators.cache import never_cache
|
||
|
|
||
|
from seahub.auth import login
|
||
|
|
||
|
from social_core.utils import setting_name
|
||
|
from social_core.actions import do_auth, do_complete, do_disconnect
|
||
|
from .utils import psa
|
||
|
|
||
|
|
||
|
NAMESPACE = getattr(settings, setting_name('URL_NAMESPACE'), None) or 'social'
|
||
|
|
||
|
# Calling `session.set_expiry(None)` results in a session lifetime equal to
|
||
|
# platform default session lifetime.
|
||
|
DEFAULT_SESSION_TIMEOUT = None
|
||
|
|
||
|
|
||
|
@never_cache
|
||
|
@psa('{0}:complete'.format(NAMESPACE))
|
||
|
def auth(request, backend):
|
||
|
return do_auth(request.backend, redirect_name=REDIRECT_FIELD_NAME)
|
||
|
|
||
|
|
||
|
@never_cache
|
||
|
@csrf_exempt
|
||
|
@psa('{0}:complete'.format(NAMESPACE))
|
||
|
def complete(request, backend, *args, **kwargs):
|
||
|
"""Authentication complete view"""
|
||
|
return do_complete(request.backend, _do_login, request.user,
|
||
|
redirect_name=REDIRECT_FIELD_NAME, request=request,
|
||
|
*args, **kwargs)
|
||
|
|
||
|
|
||
|
@never_cache
|
||
|
@login_required
|
||
|
@psa()
|
||
|
@require_POST
|
||
|
@csrf_protect
|
||
|
def disconnect(request, backend, association_id=None):
|
||
|
"""Disconnects given backend from current logged in user."""
|
||
|
return do_disconnect(request.backend, request.user, association_id,
|
||
|
redirect_name=REDIRECT_FIELD_NAME)
|
||
|
|
||
|
|
||
|
def get_session_timeout(social_user, enable_session_expiration=False,
|
||
|
max_session_length=None):
|
||
|
if enable_session_expiration:
|
||
|
# Retrieve an expiration date from the social user who just finished
|
||
|
# logging in; this value was set by the social auth backend, and was
|
||
|
# typically received from the server.
|
||
|
expiration = social_user.expiration_datetime()
|
||
|
|
||
|
# We've enabled session expiration. Check to see if we got
|
||
|
# a specific expiration time from the provider for this user;
|
||
|
# if not, use the platform default expiration.
|
||
|
if expiration:
|
||
|
received_expiration_time = expiration.total_seconds()
|
||
|
else:
|
||
|
received_expiration_time = DEFAULT_SESSION_TIMEOUT
|
||
|
|
||
|
# Check to see if the backend set a value as a maximum length
|
||
|
# that a session may be; if they did, then we should use the minimum
|
||
|
# of that and the received session expiration time, if any, to
|
||
|
# set the session length.
|
||
|
if received_expiration_time is None and max_session_length is None:
|
||
|
# We neither received an expiration length, nor have a maximum
|
||
|
# session length. Use the platform default.
|
||
|
session_expiry = DEFAULT_SESSION_TIMEOUT
|
||
|
elif received_expiration_time is None and max_session_length is not None:
|
||
|
# We only have a maximum session length; use that.
|
||
|
session_expiry = max_session_length
|
||
|
elif received_expiration_time is not None and max_session_length is None:
|
||
|
# We only have an expiration time received by the backend
|
||
|
# from the provider, with no set maximum. Use that.
|
||
|
session_expiry = received_expiration_time
|
||
|
else:
|
||
|
# We received an expiration time from the backend, and we also
|
||
|
# have a set maximum session length. Use the smaller of the two.
|
||
|
session_expiry = min(received_expiration_time, max_session_length)
|
||
|
else:
|
||
|
# If there's an explicitly-set maximum session length, use that
|
||
|
# even if we don't want to retrieve session expiry times from
|
||
|
# the backend. If there isn't, then use the platform default.
|
||
|
if max_session_length is None:
|
||
|
session_expiry = DEFAULT_SESSION_TIMEOUT
|
||
|
else:
|
||
|
session_expiry = max_session_length
|
||
|
|
||
|
return session_expiry
|
||
|
|
||
|
|
||
|
def _do_login(backend, user, social_user):
|
||
|
user.backend = '{0}.{1}'.format(backend.__module__,
|
||
|
backend.__class__.__name__)
|
||
|
# Get these details early to avoid any issues involved in the
|
||
|
# session switch that happens when we call login().
|
||
|
enable_session_expiration = backend.setting('SESSION_EXPIRATION', False)
|
||
|
max_session_length_setting = backend.setting('MAX_SESSION_LENGTH', None)
|
||
|
|
||
|
# Log the user in, creating a new session.
|
||
|
login(backend.strategy.request, user)
|
||
|
|
||
|
# Make sure that the max_session_length value is either an integer or
|
||
|
# None. Because we get this as a setting from the backend, it can be set
|
||
|
# to whatever the backend creator wants; we want to be resilient against
|
||
|
# unexpected types being presented to us.
|
||
|
try:
|
||
|
max_session_length = int(max_session_length_setting)
|
||
|
except (TypeError, ValueError):
|
||
|
# We got a response that doesn't look like a number; use the default.
|
||
|
max_session_length = None
|
||
|
|
||
|
# Get the session expiration length based on the maximum session length
|
||
|
# setting, combined with any session length received from the backend.
|
||
|
session_expiry = get_session_timeout(
|
||
|
social_user,
|
||
|
enable_session_expiration=enable_session_expiration,
|
||
|
max_session_length=max_session_length,
|
||
|
)
|
||
|
|
||
|
try:
|
||
|
# Set the session length to our previously determined expiry length.
|
||
|
backend.strategy.request.session.set_expiry(session_expiry)
|
||
|
except OverflowError:
|
||
|
# The timestamp we used wasn't in the range of values supported by
|
||
|
# Django for session length; use the platform default. We tried.
|
||
|
backend.strategy.request.session.set_expiry(DEFAULT_SESSION_TIMEOUT)
|