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.
calculate-utils-3-console-gui/libs_crutch/core/server/gen_sid.py

261 lines
8.8 KiB

# -*- coding: utf-8 -*-
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
# Session management
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import
import os
import datetime
import threading
import random
import pickle
from calculate.core.server.core_interfaces import CoreServiceInterface
from .cert_cmd import find_cert_id
class CoreWsdl(CoreServiceInterface):
sid_locker = threading.Lock()
# delete client session from file (close session)
@staticmethod
def del_sid_from_file(cls, sid):
try:
# temp file
sid_file = cls.sids_file
sid_file_t = sid_file + 'temp'
with cls.sid_locker:
fd = open(sid_file, 'r')
ft = open(sid_file_t, 'w')
while True:
try:
# read all on one record
list_sid = pickle.load(fd)
except (EOFError, IOError, KeyError):
break
# Leave all but removed
if sid != list_sid[0]:
pickle.dump(list_sid, ft)
fd.close()
ft.close()
# copy all from temp file
ft = open(sid_file_t, 'rb')
fd = open(sid_file, 'wb')
ft.seek(0)
fd.write(ft.read())
ft.close()
fd.close()
# delete temp file
os.unlink(sid_file_t)
return ['0']
except (IOError, EOFError, KeyError, OSError):
return ['1']
# find session id in file
@staticmethod
def find_sid_in_file(cls, sid):
sid_file = cls.sids_file
# create, if file not exists
with cls.sid_locker:
if not os.path.exists(sid_file):
temp = open(sid_file, 'w')
temp.close()
fd = open(sid_file, 'r')
while True:
try:
# read all on one record
list_sid = pickle.load(fd)
except (EOFError, IOError, KeyError):
break
# if session id found
if sid == list_sid[0]:
fd.close()
return 1
fd.close()
return 0
# add session id in file
@staticmethod
def add_sid_in_file(cls, sid, cert_id, lang):
# list Format (session number, cert number, time start session)
list_sid = [sid, cert_id, datetime.datetime.now()]
# session's file
if not os.path.exists(cls.sids):
os.mkdir(cls.sids)
sids_dir = cls.sids
sid_file = sids_dir + "/%d.sid" % sid
# create session's file
with cls.sid_locker:
fp = open(sid_file, 'w')
sid_list = [sid, 0, 0, lang]
pickle.dump(sid_list, fp)
fp.close()
# add session in list sessions
fd = open(cls.sids_file, 'a')
pickle.dump(list_sid, fd)
fd.close()
return 0
@staticmethod
def set_sid_lang(cls, sid, lang):
sids_dir = cls.sids
sid_file = os.path.join(sids_dir, "%d.sid" % sid)
with cls.sid_locker:
if not os.path.isfile(sid_file):
fp = open(sid_file, 'w')
fp.close()
fd = open(sid_file, 'r')
try:
list_sid = pickle.load(fd)
except (EOFError, KeyError, IOError):
list_sid = [sid, 0, 0, lang]
fd.close()
fp = open(sid_file, 'w')
list_sid[3] = lang
pickle.dump(list_sid, fp)
fp.close()
# issue number of new session (and registered its)
@staticmethod
def sid_cmp(cls, sid, cert_id, lang):
if sid < 0 or sid > cls.max_sid:
sid = 0
session = 1
# if session is new
if sid == 0:
while True:
new_sid = random.randint(1, cls.max_sid)
# flag = 1 - exists, 0 - missing in SID_FILE
if cls.find_sid_in_file(cls, new_sid) == 0:
cls.add_sid_in_file(cls, new_sid, cert_id, lang)
sid = new_sid
break
# if session is old
else:
# find number in file registered
# if not registered
if not cls.find_sid_in_file(cls, sid):
# add session id in file
cls.add_sid_in_file(cls, sid, cert_id, lang)
else:
cls.set_sid_lang(cls, sid, lang)
# set - old session
session = 0
# session id and flag (new or old) session
return [sid, session]
@staticmethod
def serv_init_session(cls, sid, lang):
day_cert = 600
cur_thread = threading.currentThread()
certificate = cur_thread.client_cert
if certificate is None:
return [-3], [0]
checked_id = find_cert_id(certificate, cls.data_path, cls.certbase)
try:
if int(checked_id) < 1:
return [-4], [0]
except ValueError:
return [-4], [0]
results = []
cert_id = checked_id
with open(cls.certbase) as fd:
t = fd.read()
# See each line
for line in t.splitlines():
# and each word in line
words = line.split()
# if in line present certificate id
if len(words) > 3:
if words[0] == checked_id:
results.append(checked_id)
date = datetime.datetime.strptime(
words[2] + ' ' + words[3], '%Y-%m-%d %H:%M:%S.%f')
d = datetime.datetime.now() - date
v = day_cert - d.days # How many days left certificate
if v < 0:
# Method deleted certificate
v = -2 # expiry date has passed
elif v > 60: # For a long time, is not displayed to
# the client
v = -1
results.append(v)
# return results
if not results:
return [-4], [0]
return results, cls.sid_cmp(cls, sid, cert_id, lang)
@staticmethod
def serv_sid_info(cls, sid):
""" Get information about sid """
cert_id = 0
results = []
sid_file = cls.sids_file
with cls.sid_locker:
fd = open(sid_file, 'r')
while 1:
try:
# read all on one record
list_sid = pickle.load(fd)
except (IOError, KeyError, EOFError):
break
# if sid found
if sid == list_sid[0]:
cert_id = list_sid[1]
fd.close()
# Get information about sid
if cert_id == 0:
return ["-1"]
with cls.sid_locker:
with open(cls.certbase) as fd:
t = fd.read()
# See each line
for line in t.splitlines():
# and each word in line
words = line.split()
# if in line present certificate id
if words[0] == str(cert_id):
# certificate id
results.append(words[0])
# Date issue certificate
results.append(words[2] + ' ' + words[3])
# ip
results.append(words[4])
# mac
results.append(words[5])
# client type
results.append(words[6])
if not os.path.exists(cls.sids):
os.makedirs(cls.sids)
sid_path = cls.sids + "/%d.sid" % sid
with open(sid_path) as fs:
# read info about session
sid_inf = pickle.load(fs)
# flag absence client
results.append(str(sid_inf[2]))
return results
return ["-2"]