1
|
# -*- coding: utf-8 -*-
|
2
|
#
|
3
|
# UnivNautes
|
4
|
# Copyright (C) 2014 Entr'ouvert
|
5
|
#
|
6
|
# This program is free software: you can redistribute it and/or modify it under
|
7
|
# the terms of the GNU Affero General Public License as published by the Free
|
8
|
# Software Foundation, either version 3 of the License, or (at your option) any
|
9
|
# later version.
|
10
|
#
|
11
|
# This program is distributed in the hope that it will be useful, but WITHOUT
|
12
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
13
|
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
14
|
# details.
|
15
|
#
|
16
|
# You should have received a copy of the GNU Affero General Public License
|
17
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
18
|
|
19
|
'''
|
20
|
delete all django sessions:
|
21
|
* if pfsenseid exists in session but is not in captiveportal.db
|
22
|
* if session is expired
|
23
|
'''
|
24
|
|
25
|
import os
|
26
|
import datetime
|
27
|
import subprocess
|
28
|
|
29
|
from django.core.management.base import BaseCommand, CommandError
|
30
|
from django.conf import settings
|
31
|
from django.contrib.sessions.backends.file import SessionStore
|
32
|
|
33
|
storage_path = settings.SESSION_FILE_PATH
|
34
|
file_prefix = settings.SESSION_COOKIE_NAME
|
35
|
|
36
|
class Command(BaseCommand):
|
37
|
help = 'remove Django sessions without pfSense equivalent'
|
38
|
|
39
|
def handle(self, *args, **options):
|
40
|
try:
|
41
|
p = subprocess.Popen(settings.UNIVNAUTES_CP_GET_SESSIONS_CMD,
|
42
|
close_fds=True,
|
43
|
stdin=subprocess.PIPE,
|
44
|
stdout=subprocess.PIPE,
|
45
|
stderr=subprocess.PIPE)
|
46
|
except OSError, e:
|
47
|
# FIXME : log
|
48
|
return
|
49
|
stdout, stderr = p.communicate()
|
50
|
|
51
|
if p.returncode != 0:
|
52
|
# FIXME : log
|
53
|
return
|
54
|
|
55
|
pfsenseids = stdout.split()
|
56
|
|
57
|
for session_file in os.listdir(storage_path):
|
58
|
if not session_file.startswith(file_prefix):
|
59
|
continue
|
60
|
session_key = session_file[len(file_prefix):]
|
61
|
session = SessionStore(session_key)
|
62
|
# When an expired session is loaded, its file is removed, and a
|
63
|
# new file is immediately created. Prevent this by disabling
|
64
|
# the create() method.
|
65
|
session.create = lambda: None
|
66
|
|
67
|
session_data = session.load()
|
68
|
# pfsenseid doesn't exist in captiveportal.db
|
69
|
if session_data.get('pfsenseid') and session_data['pfsenseid'] not in pfsenseids:
|
70
|
session.delete()
|
71
|
continue
|
72
|
|
73
|
# expired
|
74
|
modification = os.stat(session._key_to_file()).st_ctime
|
75
|
age = datetime.datetime.now() - datetime.datetime.fromtimestamp(modification)
|
76
|
if age.seconds > session.get_expiry_age():
|
77
|
session.delete()
|
78
|
continue
|
79
|
|