Django command to clean old tickets

This commit is contained in:
Valentin Samir 2015-05-28 17:30:27 +02:00
parent 9a8b724224
commit 02872d218f
5 changed files with 62 additions and 8 deletions

View file

@ -24,6 +24,7 @@ setting_default('CAS_LOGGED_TEMPLATE', 'cas_server/logged.html')
setting_default('CAS_AUTH_CLASS', auth.DjangoAuthUser) setting_default('CAS_AUTH_CLASS', auth.DjangoAuthUser)
setting_default('CAS_ST_LEN', 30) setting_default('CAS_ST_LEN', 30)
setting_default('CAS_TICKET_VALIDITY', 300) setting_default('CAS_TICKET_VALIDITY', 300)
setting_default('CAS_TICKET_TIMEOUT', 24*3600)
setting_default('CAS_PROXY_CA_CERTIFICATE_PATH', True) setting_default('CAS_PROXY_CA_CERTIFICATE_PATH', True)
setting_default('CAS_SQL_HOST', 'localhost') setting_default('CAS_SQL_HOST', 'localhost')

View file

View file

@ -0,0 +1,12 @@
from django.core.management.base import BaseCommand, CommandError
from django.utils.translation import ugettext_lazy as _
from ... import models
class Command(BaseCommand):
args = ''
help = _(u"Clean old trickets")
def handle(self, *args, **options):
for ticket_class in [models.ServiceTicket, models.ProxyTicket, models.ProxyGrantingTicket]:
ticket_class.clean()

View file

@ -10,7 +10,11 @@
# #
# (c) 2015 Valentin Samir # (c) 2015 Valentin Samir
"""models for the app""" """models for the app"""
from . import default_settings
from django.conf import settings
from django.db import models from django.db import models
from django.db.models import Q
from django.contrib import messages from django.contrib import messages
from picklefield.fields import PickledObjectField from picklefield.fields import PickledObjectField
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -18,7 +22,8 @@ from django.utils import timezone
import re import re
import os import os
import sys
from datetime import timedelta
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
from requests_futures.sessions import FuturesSession from requests_futures.sessions import FuturesSession
@ -285,6 +290,39 @@ class Ticket(models.Model):
def __unicode__(self): def __unicode__(self):
return u"Ticket(%s, %s)" % (self.user, self.service) return u"Ticket(%s, %s)" % (self.user, self.service)
@classmethod
def clean(cls):
"""Remove old ticket and send SLO to timed-out services"""
# removing old validated ticket and non validated expired tickets
cls.objects.filter(
(
Q(single_log_out=False)&Q(validate=True)
)|(
Q(validate=False)&\
Q(creation__lt=(timezone.now() - timedelta(seconds=settings.CAS_TICKET_VALIDITY)))
)
).delete()
# sending SLO to timed-out validated tickets
if settings.CAS_TICKET_TIMEOUT and \
settings.CAS_TICKET_TIMEOUT >= settings.CAS_TICKET_VALIDITY:
async_list = []
session = FuturesSession(executor=ThreadPoolExecutor(max_workers=10))
queryset = cls.objects.filter(
single_log_out=True,
validate=True,
creation__lt=(timezone.now() - timedelta(seconds=settings.CAS_TICKET_TIMEOUT))
)
for ticket in queryset:
async_list.append(ticket.logout(None, session))
queryset.delete()
for future in async_list:
if future:
try:
future.result()
except Exception as error:
sys.stderr.write("%r\n" % error)
def logout(self, request, session): def logout(self, request, session):
"""Send a SLO request to the ticket service""" """Send a SLO request to the ticket service"""
if self.validate and self.single_log_out: if self.validate and self.single_log_out:
@ -306,13 +344,16 @@ class Ticket(models.Model):
headers=headers headers=headers
) )
except Exception as error: except Exception as error:
error = utils.unpack_nested_exception(error) if request is not None:
messages.add_message( error = utils.unpack_nested_exception(error)
request, messages.add_message(
messages.WARNING, request,
_(u'Error during service logout %(service)s:\n%(error)s') % messages.WARNING,
{'service': self.service, 'error':error} _(u'Error during service logout %(service)s:\n%(error)s') %
) {'service': self.service, 'error':error}
)
else:
sys.stderr.write("%r\n" % error)
class ServiceTicket(Ticket): class ServiceTicket(Ticket):
"""A Service Ticket""" """A Service Ticket"""