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-core/core/server/request.py

588 lines
22 KiB

#-*- coding: utf-8 -*-
# Copyright 2010-2012 Calculate Ltd. 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 sys, os
import subprocess
from soaplib.serializers.primitive import String, Integer, Boolean
from soaplib.serializers.clazz import Array, ClassSerializer
from soaplib.service import rpc
from calculate.core.server.api_types import ReturnedMessage
from calculate.core.server.api_types import (Field, GroupField, ViewInfo,
ViewParams)
from calculate.lib.datavars import VariableError
from calculate.core import datavars
import traceback
class RequestInfo(ClassSerializer):
"""Parameters for method install"""
cl_page_count = String
cl_page_offset = String
class DetailRequestInfo(ClassSerializer):
"""Parameters for method install"""
cl_req_id = String
cl_req_group = String
def catchExcept():
class wrapper:
def __init__(self,f):
self.f = f
self.func_name = f.func_name
self.func_code = f.func_code
self.__doc__ = f.__doc__
self.__name__ = f.__name__
def __call__(self,selfobj,*args,**kwargs):
try:
return self.f(selfobj,*args,**kwargs)
except BaseException as e:
view = ViewInfo(groups=[])
group = GroupField(name=_("Error"),last=True)
group.fields = []
group.fields.append(Field(
name = "error",
label = str(e),
default = 'color:red;',
element = "error"))
view.groups.append(group)
print "!!!!EXCEPTION!!!!"
for i in apply(traceback.format_exception, sys.exc_info()):
print i
return view
return wrapper
class CoreWsdl:
#def create_req_table(self, )
def show_request_meth (self, dv) :
try:
page_count = int(dv.Get('cl_page_count'))
page_offset = int(dv.Get('cl_page_offset'))
#self.printSUCCESS('Current offset = %d' %page_offset)
if not page_offset:
page_offset = 0
list_req_id = dv.Get('cl_all_req_id')
if not len(list_req_id):
self.printSUCCESS('No requests')
return True
for i in range(len(list_req_id)):
list_req_id[i] = int(list_req_id[i])
list_req_id.sort()
max_id = list_req_id[len(list_req_id)-1]
if not page_count:
page_count = len(list_req_id)
head = ['id','UserName','IP','MAC','date', 'Location','Signed']
body = []
fields = ['cl_req_id','','','','','','']
#i = page_offset + 1
num_id = len(list_req_id)
if page_offset > num_id - 1:
i = list_req_id[num_id - 1]
else:
i = list_req_id[page_offset]
while True:
if len(body) == page_count or i > max_id:
break
if not i in list_req_id:
i+=1
continue
dv.Set('cl_req_id', i)
mac = dv.Get('cl_req_mac')
ip = dv.Get('cl_req_ip')
date = dv.Get('cl_req_date')
username = dv.Get('cl_req_user_name')
location = dv.Get('cl_req_location')
#self.printSUCCESS ('page number = %d' %i)
group = dv.Get('cl_req_group')
if not group:
group = 'Not signed'
body.append([str(i),username,ip,mac,date,location,group])
i+=1
if body:
self.printTable("Request Table", head, body, fields = fields, \
onClick = 'detail_request')
self.printSUCCESS('Current offset = %d' %page_offset)
except Exception,e:
for i in apply(traceback.format_exception, sys.exc_info()):
print i
print 'EXCEPT!!!!!!!!!!', e
return True
def check_req_params (self, dv, info,allvars=False,ordered=None):
errors = []
keys = sorted(filter(lambda x:x.lower() == x,
info._type_info.keys()))
if ordered:
keys = ordered + filter(lambda x:not x in ordered,
keys)
for var in keys:
# get value of variable from info
val = info.__getattribute__(var)
# check value if value send of check allvariables
if val != None or allvars:
try:
# if value not send, then get from datavars
if val == None:
val = dv.Get(var)
else:
uncomperr = dv.Uncompatible(var)
if uncomperr:
raise VariableError(uncomperr)
if not dv.Uncompatible(var):
dv.Set(var, val)
except VariableError, e:
mess = ''
messages = e.message if type(e.message) == list else [e.message]
for error in messages:
mess += str(error) + '\n'
errors.append(ReturnedMessage(type = 'error', field = var,
message = mess))
return errors
from calculate.core.server.baseClass import Basic
from calculate.core.server.decorators import Dec
def requestCommon(self,sid,info,methodname):
"""
Install common method
"""
try:
dv = self.get_cache(sid,methodname,"vars")
if not dv:
#reload(cl_install)
dv = datavars.DataVarsCore()
dv.importCore()
dv.flIniFile()
errors = self.check_req_params(dv, info,
ordered=['cl_page_count',
'cl_page_offset'],
allvars=True)
if errors:
return errors
request_meth = type("requestCommon",(self.Common,
CoreWsdl, object), {})
pid = self.startprocess(sid, target=request_meth,
method="show_request_meth",
auto_delete = True,
args_proc = (dv,))
returnmess = ReturnedMessage(type = 'pid', message = pid, expert = True)
returnmess.type = "pid"
returnmess.message = pid
dv = self.clear_cache(sid,methodname)
return [returnmess]
finally:
if dv:
self.set_cache(sid,methodname,"vars",dv,smart=False)
return []
@rpc(Integer, RequestInfo, _returns = Array(ReturnedMessage))
@Dec.check_permissions(["request"])
@Dec.console('cl-show-request')
@Dec.gui('Core',_('View Requests'),'view-certificate-import,'\
'application-certificate')
def show_request ( self, sid, info):
if not info:
mess = 'Field must be int!'
errors = []
for field in ['cl_page_count', 'cl_page_offset']:
errors.append(ReturnedMessage(type = 'error', field = field,
message = mess, expert = True))
return errors
dv = datavars.DataVarsCore()
dv.importCore()
dv.flIniFile()
dv.Set('cl_page_count', info.cl_page_count)
dv.Set('cl_page_offset', info.cl_page_offset)
self.set_cache(sid, 'show_request', "vars", dv, smart=False)
return self.requestCommon(sid,info,'show_request')
@rpc(Integer, ViewParams, _returns = ViewInfo)
@catchExcept()
def show_request_view (self, sid, params):
dv = datavars.DataVarsCore()
dv.importCore()
dv.flIniFile()
dv.addGroup(_("Requests"),
normal=('cl_page_count','cl_page_offset'),
next_label=_("Next"))
view = ViewInfo (dv)
self.set_cache(sid, 'show_request', "vars", dv, smart=False)
return view
##################### BEGIN DETAIL REQUEST METHOD ##############################
@rpc(Integer, DetailRequestInfo, _returns = Array(ReturnedMessage))
@Dec.check_permissions(["request"])
@Dec.console('cl-show-request')
@Dec.gui(_('Detail Request'))
#@Dec.gui(_('Core'),_('Detail Request'),'view-certificate-import')
def detail_request ( self, sid, info):
if not info:
mess = 'Field must be int!'
errors = []
errors.append(ReturnedMessage(type = 'error', field = 'cl_req_id',
message = mess))
return errors
dv = datavars.DataVarsCore()
dv.importCore()
dv.flIniFile()
dv.Set('cl_req_id', info.cl_req_id)
self.set_cache(sid, 'detail_request', 'dv', dv, smart = False)
return []
@rpc(Integer, ViewParams, _returns = ViewInfo)
@catchExcept()
def detail_request_view (self, sid, params):
dv = self.get_cache(sid, 'detail_request', 'dv')
if not dv:
dv = datavars.DataVarsCore()
dv.importCore()
dv.flIniFile()
dv.Get('cl_req_id')
dv.addGroup(_("Requests detail"),
normal=('cl_req_id', 'cl_req_user_name', 'cl_req_ip', 'cl_req_mac',
'cl_req_date', 'cl_req_location', 'cl_req_group',
'cl_page_count','cl_page_offset'))
view = ViewInfo (dv)
group = GroupField(name='',nextlabel=_("Done"),last=True)
group.fields = []
group.fields.append(Field(
name = "but0",
label = _("Back"),
value = "show_request",
element = "button"))
group.fields.append(Field(
name = "but1",
label = _("Confirm"),
value = "confirm_request",
element = "button"))
group.fields.append(Field(
name = "but2",
label = _("Delete"),
value = "delete_request",
element = "button"))
view.groups.append(group)
self.set_cache(sid, 'view_request', "vars", dv, smart=False)
return view
############## END DETAIL REQUEST METHOD #######################################
############## BEGIN CONFIRM REQUEST METHODS ###################################
def confirmRequestCommon(self,sid,info,methodname):
"""
Install common method
"""
try:
dv = self.get_cache(sid,methodname,"vars")
#if not dv:
#reload(cl_install)
#dv = cl_install.DataVarsInstall()
#dv.importInstall()
#dv.flIniFile()
#initfunc(dv)
errors = self.check_req_params(dv, info,
ordered=['cl_req_id'],
allvars=True)
if errors:
return errors
request_meth = type("delRequestCommon",(self.Common,
CoreWsdl, object), {})
pid = self.startprocess(sid, target=request_meth,
method="confirm_request_meth",\
args_proc = (dv,))
returnmess = ReturnedMessage(type = 'pid', message = pid)
returnmess.type = "pid"
returnmess.message = pid
dv = self.clear_cache(sid,methodname)
return [returnmess]
finally:
if dv:
self.set_cache(sid,methodname,"vars",dv,smart=False)
return []
def confirm_request_meth(self, dv):
try:
data_path = dv.Get('cl_core_data')
cert_path = dv.Get('cl_core_cert_path')
cl_req_id = str(dv.Get('cl_req_id'))
cl_req_group = str(dv.Get('cl_req_group'))
#self.startTask('Confirm Request')
self.printSUCCESS ('<b>'+_('Confirm Request')+'</b>')
self.printSUCCESS ("cl_req_id = %s" %cl_req_id)
self.printSUCCESS ("cl_req_group = %s" %cl_req_group)
server_cert = cert_path + '/root.crt'
server_key = cert_path + '/root.key'
cl_req = data_path + '/client_certs/%s.csr' %cl_req_id
cl_cert = data_path + '/client_certs/%s.crt' %cl_req_id
if not os.path.exists(cl_req):
self.printERROR (_("Signing Request %s not found") %cl_req)
return False
if os.path.exists(cl_cert):
self.printERROR (_("certificate %s already exists") %cl_cert)
return False
group = "group:%s" %cl_req_group
config = data_path + '/client_certs/ssl-client.cfg'
if os.path.exists(config):
os.unlink(config)
cfg_text = ("[ ssl_client ]\n"
"basicConstraints = CA:FALSE\n"
"nsCertType = client\n"
"keyUsage = digitalSignature, keyEncipherment\n"
"extendedKeyUsage = clientAuth\n"
"nsComment = %s") %group
fc = open(config, 'w')
fc.write(cfg_text)
fc.close()
cmd = ("openssl x509 -req -days 11000 -CA %s -CAkey %s "
"-CAcreateserial "
"-extfile %s -extensions ssl_client -in %s -out %s") \
%(server_cert, server_key, config, cl_req, cl_cert)
print cmd
PIPE = subprocess.PIPE
p = subprocess.Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE,
stderr=subprocess.STDOUT, close_fds=True)
p.wait()
self.printSUCCESS ('<b>' + _("certificate %s is signed") %cl_cert \
+ '</b>')
#self.endTask()
return True
except (KeyboardInterrupt,):
self.printERROR('Process is interrupted!')
return False
@rpc(Integer, DetailRequestInfo, _returns = Array(ReturnedMessage))
@Dec.check_permissions(["request"])
@Dec.console('cl-show-request')
@Dec.gui(_('Confirm Request'))
@catchExcept()
def confirm_request ( self, sid, info):
dv = self.get_cache(sid,'confirm_request',"vars")
if not dv:
dv = datavars.DataVarsCore()
dv.importCore()
dv.flIniFile()
try:
dv.Set('cl_req_id', info.cl_req_id)
dv.Set('cl_req_group', info.cl_req_group)
except VariableError, e:
errors = []
mess = ''
messages = e.message if type(e.message) == list else [e.message]
for error in messages:
mess += str(error) + '\n'
errors.append(ReturnedMessage(type = 'error',
field = 'cl_req_group', message = mess))
return errors
self.set_cache(sid, 'confirm_request', "vars", dv, smart=False)
return self.confirmRequestCommon(sid,info,'confirm_request')
@rpc(Integer, ViewParams, _returns = ViewInfo)
@catchExcept()
def confirm_request_view (self, sid, params):
dv = self.get_cache(sid, 'confirm_request', 'dv')
if not dv:
dv = datavars.DataVarsCore()
dv.importCore()
dv.flIniFile()
dv.Get('cl_req_id')
dv.addGroup(_("Requests detail"),
normal=('cl_req_id', 'cl_req_user_name', 'cl_req_ip', 'cl_req_mac',
'cl_req_date', 'cl_req_location', 'cl_req_group'),
next_label=_("Done"))
view = ViewInfo (dv)
group = GroupField(name=_("Requests detail"),nextlabel=_("Done"),
last=True)
group.fields = []
group.fields.append(Field(
name = "but2",
label = "Confirm",
value = "confirm_request",
element = "button"))
view.groups.append(group)
self.set_cache(sid, 'delete_request', "vars", dv, smart=False)
return view
############## END CONFIRM REQUEST METHODS ###################################
def delRequestCommon(self,sid,info,methodname):
"""
Install common method
"""
try:
dv = self.get_cache(sid,methodname,"vars")
#if not dv:
#reload(cl_install)
#dv = cl_install.DataVarsInstall()
#dv.importInstall()
#dv.flIniFile()
#initfunc(dv)
errors = self.check_req_params(dv, info,
ordered=['cl_req_id'],
allvars=True)
if errors:
return errors
request_meth = type("delRequestCommon",(self.Common,
CoreWsdl, object), {})
pid = self.startprocess(sid, target=request_meth,
method="del_request_meth",\
args_proc = (dv,))
returnmess = ReturnedMessage(type = 'pid', message = pid)
returnmess.type = "pid"
returnmess.message = pid
dv = self.clear_cache(sid,methodname)
return [returnmess]
finally:
if dv:
self.set_cache(sid,methodname,"vars",dv,smart=False)
return []
def del_request_meth(self, dv):
#ob = datavars.DataVarsCore()
#ob.importCore()
# set var env
#ob.flIniFile()
try:
data_path = dv.Get('cl_core_data')
certbase = dv.Get('cl_core_database')
id_del_req = str(dv.Get('cl_req_id'))
self.startTask("id_del_req = %s" %id_del_req)
print "id_del_req = ", id_del_req
request = data_path + '/client_certs/%s.csr' %id_del_req
cert = data_path + '/client_certs/%s.crt' %id_del_req
# chect exists request and certificate files
if not os.path.exists(request) and not os.path.exists(cert):
self.printERROR (
_("Request and certificate with id = %s not found!") \
%id_del_req)
return False
if not os.path.exists(request):
self.printERROR (_("request %s not found!") %request)
if os.path.exists(cert):
self.printERROR (_("This request has already been signed"))
# create temp file
ft = open(certbase + '_temp', 'w')
with open(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 not words[0] == id_del_req:
ft.write(line + '\n')
ft.close()
fd.close()
ft = open(certbase + '_temp', 'rb')
fc = open(certbase, 'wb')
ft.seek(0)
fc.write(ft.read())
ft.close()
fc.close()
os.unlink(certbase + '_temp')
try:
if os.path.exists(request):
os.unlink (request)
self.printSUCCESS (_("request deleted"))
if os.path.exists(cert):
os.unlink (cert)
self.printSUCCESS (_("certificate deleted"))
except:
self.printERROR (_("delete file error!"))
self.endTask()
except KeyboardInterrupt:
self.endTask()
return False
except Exception, e:
msg = e.message
if not msg:
msg = e.reason
self.printERROR (_("Exception!%s") %msg)
return False
@rpc(Integer, DetailRequestInfo, _returns = Array(ReturnedMessage))
@Dec.check_permissions(["request"])
@Dec.console('cl-show-request')
@Dec.gui(_('Delete Request'))
@catchExcept()
def delete_request ( self, sid, info):
#dv = self.get_cache(sid,'delete_request',"vars")
#if not dv:
dv = datavars.DataVarsCore()
dv.importCore()
dv.flIniFile()
dv.Set('cl_req_id', info.cl_req_id)
self.set_cache(sid, 'delete_request', "vars", dv, smart=False)
return self.delRequestCommon(sid,info,'delete_request')
@rpc(Integer, ViewParams, _returns = ViewInfo)
@catchExcept()
def delete_request_view (self, sid, params):
dv = self.get_cache(sid, 'detail_request', 'dv')
if not dv:
dv = datavars.DataVarsCore()
dv.importCore()
dv.flIniFile()
dv.Get('cl_req_id')
dv.addGroup(_("Requests delete"),
normal=('cl_req_id', 'cl_req_user_name', 'cl_req_ip', 'cl_req_mac',
'cl_req_date', 'cl_req_location', 'cl_req_group'),
next_label=_("Done"))
view = ViewInfo (dv)
group = GroupField(name=_("Requests detail"),nextlabel=_("Done"),
last=True)
group.fields = []
group.fields.append(Field(
name = "but2",
label = "Delete",
value = "delete_request",
element = "button"))
view.groups.append(group)
self.set_cache(sid, 'delete_request', "vars", dv, smart=False)
return view