#-*- 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 (''+_('Confirm Request')+'') 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 ('' + _("certificate %s is signed") %cl_cert \ + '') #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