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.
404 lines
15 KiB
404 lines
15 KiB
# -*- coding: utf-8 -*-
|
|
|
|
# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
|
|
#
|
|
# 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.
|
|
|
|
import os
|
|
import sys
|
|
|
|
from spyne import rpc
|
|
|
|
from spyne import Service
|
|
|
|
from spyne import String, Integer, Array
|
|
|
|
from calculate.core.server.core_interfaces import CoreServiceInterface
|
|
from calculate.lib.utils.files import readFile
|
|
|
|
_ = lambda x: x
|
|
from calculate.lib.cl_lang import getLazyLocalTranslate, setLocalTranslate
|
|
|
|
setLocalTranslate('cl_core3', sys.modules[__name__])
|
|
|
|
__ = getLazyLocalTranslate(_)
|
|
|
|
from clean import sid_monitor, monitor
|
|
from tasks import restart, dbus_stop
|
|
from loaded_methods import LoadedMethods
|
|
from api_types import Message, ReturnProgress, Table
|
|
import post_cert
|
|
import post_request
|
|
import send_cert
|
|
|
|
# class Basic(CoreServiceInterface):
|
|
class Basic(Service, CoreServiceInterface):
|
|
""" Basic server class """
|
|
|
|
SERV_VERS = 0.11
|
|
glob_process_dict = {}
|
|
process_pid = {}
|
|
glob_progress_dict = {}
|
|
glob_table_dict = {}
|
|
glob_frame_list = {}
|
|
manager = None
|
|
|
|
data_path = None
|
|
certbase = None
|
|
rights = None
|
|
sids = None
|
|
pids = None
|
|
sids_file = None
|
|
ssl_certificate = None
|
|
ssl_private_key = None
|
|
cachedict = {}
|
|
|
|
#workaround: Spyne won't let us use self ref in @rpc,
|
|
# and ctx leads to original service class (Basic in this case)
|
|
# but some methods are gathered from CoreWsdl classes, so we need
|
|
# a ref to combined class
|
|
comb_class_ref = None
|
|
|
|
# function getting object from cache
|
|
@staticmethod
|
|
def get_cache(sid, meth_name, obj_name):
|
|
if sid in Basic.cachedict:
|
|
if meth_name in Basic.cachedict[sid]:
|
|
if obj_name in Basic.cachedict[sid][meth_name]:
|
|
return Basic.cachedict[sid][meth_name][obj_name]
|
|
return None
|
|
|
|
# function placing object in cache
|
|
@staticmethod
|
|
def set_cache(sid, meth_name, obj_name, obj, smart=True):
|
|
try:
|
|
if sid not in Basic.cachedict:
|
|
Basic.cachedict[sid] = {}
|
|
if meth_name not in Basic.cachedict[sid]:
|
|
Basic.cachedict[sid][meth_name] = {}
|
|
if obj_name not in Basic.cachedict[sid][meth_name]:
|
|
Basic.cachedict[sid][meth_name][obj_name] = obj
|
|
return True
|
|
if smart:
|
|
for var_name, var_value in obj.__dict__.viewitems():
|
|
if var_value is not None:
|
|
setattr(Basic.cachedict[sid][meth_name][obj_name],
|
|
var_name, var_value)
|
|
else:
|
|
Basic.cachedict[sid][meth_name][obj_name] = obj
|
|
return True
|
|
except Exception as e:
|
|
if isinstance(e, SyntaxError):
|
|
raise
|
|
return False
|
|
|
|
|
|
|
|
@staticmethod
|
|
def clear_cache(sid, meth_name=None, obj_name=None):
|
|
if sid not in Basic.cachedict:
|
|
return True
|
|
if meth_name:
|
|
if meth_name not in Basic.cachedict[sid]:
|
|
return True
|
|
|
|
if obj_name:
|
|
if obj_name not in Basic.cachedict[sid][meth_name]:
|
|
return True
|
|
else:
|
|
obj = Basic.cachedict[sid][meth_name].pop(obj_name, None)
|
|
if hasattr(obj, 'close'):
|
|
obj.close()
|
|
else:
|
|
method_dict = Basic.cachedict[sid].pop(meth_name, None)
|
|
for val_obj in method_dict.values():
|
|
if hasattr(val_obj, 'close'):
|
|
val_obj.close()
|
|
else:
|
|
session_dict = Basic.cachedict.pop(sid, None)
|
|
for method_dict in session_dict.values():
|
|
for val_obj in method_dict.values():
|
|
if hasattr(val_obj, 'close'):
|
|
val_obj.close()
|
|
|
|
@staticmethod
|
|
def clear_cache_method(method=None):
|
|
for k, v in Basic.cachedict.items():
|
|
Basic.clear_cache(k, method)
|
|
|
|
@staticmethod
|
|
def set_paths(data_path, certbase, serv_certbase, rights,
|
|
group_rights, sids, pids, sids_pids, sids_file, pids_file,
|
|
max_sid, max_pid, cert_path, log_filename,
|
|
cert="server.crt", key="server.key"):
|
|
""" set system path for main class """
|
|
Basic.data_path = data_path
|
|
Basic.certbase = certbase
|
|
Basic.serv_certbase = serv_certbase
|
|
Basic.rights = rights
|
|
Basic.group_rights = group_rights
|
|
Basic.sids = sids
|
|
Basic.pids = pids
|
|
Basic.sids_pids = sids_pids
|
|
Basic.sids_file = sids_file
|
|
Basic.pids_file = pids_file
|
|
Basic.ssl_certificate = cert
|
|
Basic.ssl_private_key = key
|
|
Basic.cert_path = cert_path
|
|
Basic.max_sid = int(max_sid)
|
|
Basic.max_pid = int(max_pid)
|
|
Basic.log_filename = log_filename
|
|
|
|
|
|
@staticmethod
|
|
def set_comb_class_ref(comb_class_ref):
|
|
Basic.comb_class_ref = comb_class_ref
|
|
|
|
@staticmethod
|
|
def run_tasks():
|
|
"""
|
|
Запуситить регулярные задачи
|
|
"""
|
|
import threading
|
|
# start monitor and sid_monitor threads
|
|
monitoring = threading.Thread(target=monitor,
|
|
args=(Basic.certbase, Basic.sids_file))
|
|
sid_mon = threading.Thread(target=sid_monitor,
|
|
args=(Basic.sids_file, Basic.sids, Basic.comb_class_ref))
|
|
restart_watchdog = threading.Thread(target=restart,
|
|
args=(Basic.comb_class_ref.glob_process_dict,))
|
|
dbus_stop_mon = threading.Thread(target=dbus_stop,
|
|
args=(Basic.comb_class_ref.glob_process_dict, Basic.comb_class_ref.sids, Basic.comb_class_ref))
|
|
threads = []
|
|
for thread, success, failed in (
|
|
(monitoring, _("General monitoring started"),
|
|
_("Monitoring error")),
|
|
(sid_mon, _("Session monitoring started"),
|
|
_("Session monitoring failed")),
|
|
(restart_watchdog, _("Restart watchdog started"),
|
|
_("Restart watchdog failed")),
|
|
(dbus_stop_mon, _("Inactive watchdog started"),
|
|
_("Inactive watchdog failed"))):
|
|
try:
|
|
threads.append(thread)
|
|
thread.daemon = True
|
|
thread.start()
|
|
print success
|
|
except Exception:
|
|
print failed
|
|
print
|
|
|
|
@staticmethod
|
|
def killall():
|
|
sys.stdout.write('\n' + _('Closing all processes') + '...')
|
|
sys.stdout.flush()
|
|
import time
|
|
# Waiting for closing
|
|
for pid in Basic.process_pid.keys():
|
|
try:
|
|
os.kill(Basic.process_pid[pid].pid, 2)
|
|
except OSError:
|
|
pass
|
|
while True:
|
|
num_active_process = 0
|
|
for pid in Basic.process_pid.keys():
|
|
if Basic.process_pid[pid].is_alive():
|
|
num_active_process += 1
|
|
|
|
if num_active_process:
|
|
sys.stdout.write('.')
|
|
sys.stdout.flush()
|
|
else:
|
|
print '\n' + _('All processes are closed.')
|
|
return 0
|
|
time.sleep(0.5)
|
|
|
|
|
|
@rpc(_returns=Array(Integer))
|
|
def post_cert(ctx):
|
|
# import post_cert
|
|
returns = post_cert.serv_post_cert(Basic.comb_class_ref)
|
|
return returns
|
|
|
|
@rpc(Integer, _returns=Integer)
|
|
def clear_session_cache(ctx, sid):
|
|
check_sid = Basic.comb_class_ref.check_sid_cert(Basic.comb_class_ref, sid)
|
|
if not check_sid:
|
|
return 1
|
|
# clear cache
|
|
Basic.clear_cache(sid)
|
|
return 0
|
|
|
|
@rpc(Integer, String, _returns=Integer)
|
|
def clear_method_cache(ctx, sid, method_name):
|
|
check_sid = Basic.comb_class_ref.check_sid_cert(Basic.comb_class_ref, sid)
|
|
if not check_sid:
|
|
return 1
|
|
# clear cache
|
|
Basic.clear_cache(sid, method_name)
|
|
return 0
|
|
|
|
@rpc(Integer, Integer, _returns=Integer)
|
|
def clear_pid_cache(ctx, sid, pid):
|
|
if not Basic.comb_class_ref.check_sid_cert(Basic.comb_class_ref, sid):
|
|
return 1
|
|
|
|
if pid in Basic.comb_class_ref.find_sid_pid_file(Basic.comb_class_ref, sid):
|
|
# clear pid cache
|
|
Basic.comb_class_ref.delete_pid(Basic.comb_class_ref, sid, pid)
|
|
return 0
|
|
|
|
return 2
|
|
|
|
@rpc(Integer, Integer, String, _returns=Array(Integer))
|
|
def post_sid(self, sid, cert_id, lang):
|
|
return Basic.comb_class_ref.sid_cmp(Basic.comb_class_ref, sid, cert_id, lang)
|
|
|
|
@rpc(Integer, String, _returns=(Array(Integer), Array(Integer)))
|
|
def init_session(ctx, sid, lang):
|
|
return Basic.comb_class_ref.serv_init_session(Basic.comb_class_ref, sid, lang)
|
|
|
|
@rpc(Integer, _returns=Array(String))
|
|
# @Dec.check_permissions(['del_sid'])
|
|
def del_sid(self, sid):
|
|
flag = Basic.comb_class_ref.del_sid_pid(Basic.comb_class_ref, sid)
|
|
Basic.comb_class_ref.clear_cache(int(sid))
|
|
if not flag:
|
|
return Basic.comb_class_ref.del_sid_from_file(Basic.comb_class_ref,
|
|
sid)
|
|
else:
|
|
return ['-1']
|
|
|
|
@rpc(Integer, Integer, _returns=Integer)
|
|
def pid_kill(ctx, pid, sid):
|
|
return Basic.comb_class_ref.serv_pid_kill(Basic.comb_class_ref, pid, sid)
|
|
|
|
@rpc(Integer, _returns=Array(Integer))
|
|
def list_pid(ctx, sid):
|
|
return Basic.comb_class_ref.find_sid_pid_file(Basic.comb_class_ref, sid)
|
|
|
|
@rpc(Integer, String, _returns=Array(Array(String)))
|
|
def get_methods(ctx, sid, client_type):
|
|
return map(lambda x: map(str, x),
|
|
Basic.comb_class_ref.serv_get_methods(Basic.comb_class_ref, client_type))
|
|
|
|
@rpc(Integer, _returns=Array(String))
|
|
@LoadedMethods.core_method(rights=["get-sessions"])
|
|
# @Dec.console('list-session')
|
|
def get_sessions(ctx, sid):
|
|
if not Basic.comb_class_ref.check_sid_cert(Basic.comb_class_ref, sid):
|
|
return ['']
|
|
return Basic.comb_class_ref.serv_get_sessions(Basic.comb_class_ref)
|
|
|
|
@rpc(Integer, Integer, _returns=Array(String))
|
|
# @Dec.check_permissions(["pid_info"])
|
|
def pid_info(ctx, sid, pid):
|
|
return Basic.comb_class_ref.serv_pid_info(Basic.comb_class_ref, sid, pid)
|
|
|
|
@rpc(Integer, _returns=Array(String))
|
|
@LoadedMethods.core_method(rights=["session_info"])
|
|
def sid_info(ctx, sid):
|
|
return Basic.comb_class_ref.serv_sid_info(Basic.comb_class_ref, sid)
|
|
|
|
@rpc(Integer, String, _returns=Array(String))
|
|
@LoadedMethods.check_permissions(["view_cert_right"])
|
|
# @Dec.console('view-cert-right')
|
|
# @Dec.gui('System')
|
|
def view_cert_right(ctx, cert_id, client_type):
|
|
return Basic.comb_class_ref.serv_view_cert_right(Basic.comb_class_ref,
|
|
cert_id, Basic.data_path, client_type)
|
|
|
|
@rpc(Integer, _returns=Integer)
|
|
def active_client(ctx, sid):
|
|
return Basic.comb_class_ref.active_clients(Basic.comb_class_ref, sid)
|
|
|
|
@rpc(String, String, String, String, _returns=String)
|
|
def post_client_request(ctx, request, ip, mac, client_type):
|
|
res = post_request.serv_post_client_request(request, Basic.data_path,
|
|
ip, mac, client_type,
|
|
Basic.certbase,
|
|
Basic.cert_path)
|
|
return res
|
|
|
|
@rpc(String, String, _returns=Array(String))
|
|
def get_client_cert(ctx, req_id, request):
|
|
res = post_request.serv_get_client_cert(req_id, request,
|
|
Basic.data_path, Basic.certbase,
|
|
Basic.cert_path)
|
|
return res
|
|
|
|
@rpc(String, String, String, _returns=String)
|
|
def post_server_request(ctx, request, ip, mac):
|
|
res = post_request.serv_post_server_request(request, Basic.data_path,
|
|
ip, mac, Basic.serv_certbase,
|
|
Basic.cert_path)
|
|
return res
|
|
|
|
@rpc(String, String, _returns=Array(String))
|
|
def get_server_cert(ctx, req_id, request):
|
|
res = post_request.serv_get_server_request(req_id, request,
|
|
Basic.data_path,
|
|
Basic.serv_certbase,
|
|
Basic.cert_path)
|
|
return res
|
|
|
|
@rpc(_returns=String)
|
|
def get_crl(self):
|
|
if os.path.exists(Basic.data_path + '/server_certs/ca.crl'):
|
|
return readFile(Basic.data_path + '/server_certs/ca.crl')
|
|
return ' '
|
|
|
|
@rpc(_returns=String)
|
|
def get_server_host_name(ctx):
|
|
import OpenSSL
|
|
|
|
cert = readFile(Basic.ssl_certificate)
|
|
cert_obj = OpenSSL.crypto.load_certificate(
|
|
OpenSSL.SSL.FILETYPE_PEM, cert)
|
|
subject = cert_obj.get_subject().get_components()
|
|
for subj in subject:
|
|
if subj[0] == 'CN':
|
|
return subj[1]
|
|
return ''
|
|
|
|
@rpc(_returns=String)
|
|
def get_ca(ctx):
|
|
return send_cert.get_ca(Basic.cert_path)
|
|
|
|
#moved here from api_types:
|
|
|
|
@rpc(Integer, Integer, String, _returns=Array(Message))
|
|
# @Dec.check_permissions()
|
|
def get_frame(ctx, sid, pid, client_type):
|
|
return Basic.comb_class_ref.client_get_frame(Basic.comb_class_ref, sid, pid, client_type)
|
|
|
|
@rpc(Integer, Integer, _returns=Array(Message))
|
|
def get_entire_frame(self, sid, pid):
|
|
return Basic.comb_class_ref.client_get_entire_frame(Basic.comb_class_ref, sid, pid)
|
|
|
|
@rpc(Integer, Integer, Integer, _returns=ReturnProgress)
|
|
# @Dec.check_permissions()
|
|
def get_progress(self, sid, pid, id):
|
|
return Basic.comb_class_ref.client_get_progress(Basic.comb_class_ref, sid, pid, id)
|
|
|
|
@rpc(Integer, Integer, Integer, _returns=Table)
|
|
# @Dec.check_permissions()
|
|
def get_table(self, sid, pid, id):
|
|
return Basic.comb_class_ref.client_get_table(Basic.comb_class_ref, sid, pid, id)
|
|
|
|
# get messages, transferred from client
|
|
@rpc(Integer, Integer, String, _returns=Message)
|
|
# @Dec.check_permissions()
|
|
def send_message(self, sid, pid, text):
|
|
return Basic.comb_class_ref.client_send_message(Basic.comb_class_ref, sid, pid, text)
|