mirror of https://github.com/jumpserver/jumpserver
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
2.1 KiB
68 lines
2.1 KiB
import time |
|
from threading import Thread |
|
|
|
from django.conf import settings |
|
from django.contrib.auth import logout |
|
from django.contrib.auth.models import AnonymousUser |
|
from rest_framework import generics |
|
from rest_framework import status |
|
from rest_framework.response import Response |
|
|
|
from common.sessions.cache import user_session_manager |
|
from common.utils import get_logger |
|
|
|
__all__ = ['UserSessionApi'] |
|
|
|
logger = get_logger(__name__) |
|
|
|
|
|
class UserSessionManager: |
|
|
|
def __init__(self, request): |
|
self.request = request |
|
self.session = request.session |
|
|
|
def connect(self): |
|
user_session_manager.add_or_increment(self.session.session_key) |
|
|
|
def disconnect(self): |
|
user_session_manager.decrement(self.session.session_key) |
|
if self.should_delete_session(): |
|
thread = Thread(target=self.delay_delete_session) |
|
thread.start() |
|
|
|
def should_delete_session(self): |
|
return (self.session.modified or settings.SESSION_SAVE_EVERY_REQUEST) and \ |
|
not self.session.is_empty() and \ |
|
self.session.get_expire_at_browser_close() and \ |
|
not user_session_manager.check_active(self.session.session_key) |
|
|
|
def delay_delete_session(self): |
|
timeout = 6 |
|
check_interval = 0.5 |
|
|
|
start_time = time.time() |
|
while time.time() - start_time < timeout: |
|
time.sleep(check_interval) |
|
if user_session_manager.check_active(self.session.session_key): |
|
return |
|
|
|
logout(self.request) |
|
|
|
|
|
class UserSessionApi(generics.RetrieveDestroyAPIView): |
|
permission_classes = () |
|
|
|
def retrieve(self, request, *args, **kwargs): |
|
if isinstance(request.user, AnonymousUser): |
|
return Response(status=status.HTTP_403_FORBIDDEN) |
|
|
|
UserSessionManager(request).connect() |
|
return Response(status=status.HTTP_200_OK, data={'ok': True}) |
|
|
|
def destroy(self, request, *args, **kwargs): |
|
if isinstance(request.user, AnonymousUser): |
|
return Response(status=status.HTTP_403_FORBIDDEN) |
|
|
|
UserSessionManager(request).disconnect() |
|
return Response(status=status.HTTP_200_OK, data={'ok': True})
|
|
|