def session_last_session_info(uid, fio, equip_kind): u"""Информация о последней открытой или закрытой pc-, терминальной или мобильной сессии. equip_kind - вид оборудования: 'T'-терминал, 'M'-мобильне устройство, 'P' и другое -PC """ #print "%s: session_last_session_info" % (time.strftime('%H:%M:%S',time.localtime())) # если error_msg пусто, то go_url и info должно быть заполнено, если не произошёл Exception и LAST_ID_SYSTEM is not None error_msg = '' go_url = None info = None ses_info = db.dbExec(sql="select * from EQUIP_LAST_SESSION_INFO(?,?)", params=[uid, equip_kind], fetch='one', id_system=-1) # ошибка обновления сессии if ses_info['ERROR_CODE'] != 0 and ses_info['ERROR_CODE'] != 3: from py_utils import iif error_msg = 'Ошибка получения информации о %(KIND)s сессии: %(ERROR_MSG)s. UID=%(UID)s, FIO=%(FIO)s' % \ {'KIND': iif(equip_kind=='T', 'терминальной', iif(equip_kind=='M', 'мобильной', 'PC-')), 'ERROR_MSG': ses_info['ERROR_MSG'], 'UID': uid, 'FIO': fio } else: go_url = si.get_full_ref_name_by_id_system(ses_info['LAST_ID_SYSTEM']) # м.б. None, если LAST_ID_SYSTEM is None info = ses_info return error_msg, go_url, info
def session_close(uid, fio, equip_kind, reason, closed_by=None, conEngine=None): u"""Закрытие pc-, терминальной или мобильной сессии по пользователю. Вызывается для PC- и мобильных сессий из exit, по тайм-ауту для PC-сессий, для терминальных и мобильных при скане ШК выхода либо после закрытия администратором, при использовании слоёв - скриптом, проверяющим окончание срока действия тарифа. Очищает старую историю за config.SESSION_MAX_HISTORY дней назад по переданному типу сессий equip_kind. equip_kind - вид оборудования: 'T'-терминал, 'M'-мобильне устройство, 'P' и другое -PC reason - Причина закрытия сессии: 0.Зарезервировано на будущее, 1.Выход(exit или ШК выхода), 2.Автозакрытие из веб(только для PC), 3.Открытие новой(продление)(вход с другого браузера,через index,скан ШК входа), 4.Закрыта администратором 5.Закрыта из-за окончания действия тарифа (только для PC, т.к. в случае продления тарифа для терминальных и мобильных сессий останутся незакрытые задания) """ # print "%s: session_close" % (time.strftime('%H:%M:%S',time.localtime())) error_msg = '' ses_close = db.dbExec(sql="select * from EQUIP_SESSION_CLOSE(?,?,?,?)", params=[uid, equip_kind, reason, closed_by], fetch='one', id_system=-1, con=conEngine) # ошибка закрытия сессии # ERROR_CODE = 3 - если PC-сессия очищена по тайм-ауту, а потом был нажат exit, или наоборот, то не считаем это ошибкой # ERROR_CODE = 3 - для терминальных и мобильных сессий - это ошибка if ses_close['ERROR_CODE'] not in (0, 3) and equip_kind not in ('T', 'M') \ or ses_close['ERROR_CODE'] != 0 and equip_kind in ('T', 'M'): from py_utils import iif error_msg = 'Ошибка закрытия %(KIND)s сессии: %(ERROR_MSG)s. UID=%(UID)s, FIO=%(FIO)s ' % \ {'KIND': iif(equip_kind=='T', 'терминальной', iif(equip_kind=='M', 'мобильной', 'PC-')), 'ERROR_MSG': ses_close['ERROR_MSG'], 'UID': uid, 'FIO': fio } return error_msg, ses_close['WEB_SESSION_ID']
def session_open(uid, fio, equip_kind, termnum=None): u"""Открытие pc-, терминальной или мобильной сессии. Предварительно выполняет закрытие старой сессии и очистку истории за config.SESSION_MAX_HISTORY дней назад по пользователю и виду сессий. equip_kind - вид оборудования: 'T'-терминал, 'M'-мобильне устройство, 'P' и другое -PC termnum учитывается лишь в случае терминальных и мобильных сессий. Если же он не передан и equip_kind in ('M', 'T'), (что реально не происходит), новая сессия не будет открыта, и текст сообщения об ошибке будет содержать "Сессия утеряна" (в смысле утери номера терминала). """ #print "%s: session_open" % (time.strftime('%H:%M:%S',time.localtime())) error_msg = '' old_web_session_id = None ses_open=db.dbExec(sql="select * from EQUIP_SESSION_OPEN(?,?,?,?)", params=[uid, equip_kind, termnum, session_id()], fetch='one', id_system=-1) # ошибка открытия PC-сессии if ses_open['ERROR_CODE'] != 0: from py_utils import iif error_msg = 'Ошибка открытия %(KIND)s сессии: %(ERROR_MSG)s. UID=%(UID)s, FIO=%(FIO)s' % \ {'KIND': iif(equip_kind=='T', 'терминальной', iif(equip_kind=='M', 'мобильной', 'PC-')), 'ERROR_MSG': ses_open['ERROR_MSG'], 'UID': uid, 'FIO': fio } old_web_session_id = ses_open['CLOSED_WEB_SESSION_ID'] return old_web_session_id, error_msg
def tickets_get(self, ticketId, develId, reason, dtBeg, dtEnd, ticket, adminId, idBase, perm, only_no_deleted, ip): """perm is None - все виды тикетов, 0 - временные, 1 - перманентные ip - один из ip-адресов разработчика, на которые выдан тикет """ tickets_ro=self.dbExec(sql="select TICKET_ID, DEVEL_ID, DEVEL_FIO, REASON, GRANT_STAMP, TICKET, DELETED_TIME, ADMIN_FIO, DB_IP, DB_NAME, PERM, ALLOWED_IPS" \ " from T_GET(?,?,?,?,?,?,?,?,?,?) " + pu.iif(only_no_deleted, ' WHERE DELETED_TIME IS NULL', ''), params=(ticketId, develId, reason, dtBeg, dtEnd, ticket, adminId, idBase, perm, ip), fetch='all')['datalist'] tickets = [] #копируем tickets_ro в tickets #по строкам for dic_ro in tickets_ro: dic = {} #по столбцам for key, val in dic_ro.items(): dic[key] = val tickets.append(dic) #replace private ip for base in tickets: base['DB_IP'] = db.db_ip_to_private(base['DB_IP']) tickets = {'datalist': tickets} return tickets
def login_term(self, code='', mes=''): if mes != '': return self.drawTemplate(templ=pu.iif(cpu.isMobile(), login_index_mob, login_index_term), data=[{'mes':mes}], draw_wo_login=True) if code == '': return self.drawTemplate(templ=pu.iif(cpu.isMobile(), login_index_mob, login_index_term), data=[{'mes':pu.iif(cpu.isMobile(), 'QR-код пуст', 'ШК пуст')}], draw_wo_login=True) #если мы остались на том же URL (/login_term), надо пробрасывать на $cfg.TERMINAL_START_PAGE, в котором забит termnum #т.к. проставляются переменные termnum и другие только через SysLogin.index #если на другом URL - срабатывает sec из secure.secure_access и перенаправляет на $cfg.TERMINAL_START_PAGE #через cpu.goToIndex termnum = self.getSesVar('termnum') if termnum is None: return self.drawTemplate(templ=pu.iif(cpu.isMobile(), login_index_mob, login_index_term), data=[{'mes':'termnum_is_lost'}], draw_wo_login=True) return self.draw_system_list_term(code=code, termnum=termnum)
def ajaxTicketDelAll(self, perm): "Удалять можно только временные или только постоянные тикеты: если perm истинен, то постоянные, иначе - временные" tickets = [] """for dic in self.dbExec(sql="select TICKET_ID, DEVEL_ID, DEVEL_FIO, REASON, GRANT_STAMP, TICKET, DELETED_TIME, ADMIN_FIO, DB_IP, DB_NAME" \ " from T_GET(?,?,?,?,?,?,?,?) WHERE DELETED_TIME IS NULL", params=(None, None, None, mxToday(), LastTodayTime(), None, None, None), fetch='all')['datalist']:""" for dic in self.tickets_get(ticketId=None, develId=None, reason=None, dtBeg=mxToday(), dtEnd=LastTodayTime(), ticket=None, adminId=None, idBase=None, perm=self.cStrE(perm), only_no_deleted=True, ip=None)['datalist']: tickets.append(dic) dic = self.dbExec(sql="select DELETED_TIME from T_MARK_DEL_ALL(?)", params=[self.cStrE(perm)], fetch='one') if dic is not None: deleted_time = formatMxDateTime(dic['DELETED_TIME'], format='%H:%M', sformatFrom='%H:%M:%S') else: deleted_time = '' #для каждой зарегистрированной БД вызываем очистку каталогов тикетов на серверах (за сегодня) #for dic in self.dbExec(sql="select TICKETS_PATH_HOME, SERVER_IP, SERVER_USER from ENGINE_GET_BASES_INFO(NULL)", fetch='all')['datalist']: for base in db.get_bases_info()['dbs']: db.dbExecDirect(sql="delete from K_IP_CHECK where PERM is not null and PERM " + pu.iif(perm!='0', '<>0', '=0'), params=[], fetch='none', id_base=base['ID_BASE'] ) dublin.dropTodayLinks(links_path=pu.iif(perm!='0', base['TICKETS_PERM_PATH_HOME'], base['TICKETS_PATH_HOME']), user=base['SERVER_USER'], ip=base['SERVER_IP']) #по всем тикетам, попавшим в фильтр for dic in tickets: pu.send_devel_mail(subject='Тикет удалён', body='Тикет: %s\nIP/port: %s\nБД: %s\nID тикета: %s\nПерманент: %s\nВремя удаления: %s%s' \ % (dic['TICKET'], dic['DB_IP'], dic['DB_NAME'], dic['TICKET_ID'], pu.iif(dic['PERM'], 'Да', 'Нет'), deleted_time, signature), id_devel=dic['DEVEL_ID']) return self.pyDumps(ext_data={'DELETED_TIME': deleted_time})
def session_update(uid, fio, equip_kind, ip_addr, user_agent, id_system): u"""Обновление параметров pc-, терминальной или мобильной сессии по пользователю. Вызывается при входе в интерфейсы. equip_kind - вид оборудования: 'T'-терминал, 'M'-мобильне устройство, 'P' и другое -PC ip_addr, user_agent, id_system - обновляемые параметры сессии """ #print "%s: session_update" % (time.strftime('%H:%M:%S',time.localtime())) error_msg = '' ses_update=db.dbExec(sql="select * from EQUIP_SESSION_UPDATE(?,?,?,?,?)", params=[uid, equip_kind, ip_addr, user_agent, id_system], fetch='one', id_system=-1) # ошибка обновления сессии if ses_update['ERROR_CODE'] != 0: from py_utils import iif error_msg = 'Ошибка обновления %(KIND)s сессии: %(ERROR_MSG)s. UID=%(UID)s, FIO=%(FIO)s' % \ {'KIND': iif(equip_kind=='T', 'терминальной', iif(equip_kind=='M', 'мобильной', 'PC-')), 'ERROR_MSG': ses_update['ERROR_MSG'], 'UID': uid, 'FIO': fio } return error_msg
def passwd(self, fields={}, success=None): "форма смены пароля и генерации ШК" has_barcode = pu.iif( getattr(cfg, 'TERMINAL_link', None) in granted_system_refs( self.getUserVar('uid')) or getattr(cfg, 'MOBILE_link', None) in granted_system_refs( self.getUserVar('uid')), '1', '') return self.drawTemplate(templ=passwd, data=[ fields, { 'system_name': self.sysname, 'has_barcode': has_barcode, 'success': success } ])
def exception_inner(self, exception='', title='', tmpl_name=None, data=None): import datetime_utils as dtu data_all = {'time': dtu.GetCurDateTime(shortYear=None, dateSeparator='.', timeSeparator=':'), 'title': title, 'exception_text': exception.replace('\\n', '<br>'), 'url': cfg.init_url, 'back': 1, 'termnum': self.getSesVar('termnum'), 'fti': self.getSesVar('fti'), 'fmi': self.getSesVar('fmi'), 'traceback': pu.iif(cfg.show_tracebacks, cherrypy._cperror.format_exc().replace('\\n','<br>').replace('\n','<br>'), ''), 'getSesVar': self.getSesVar } if data: data_all.update(data) exc = cpu.import_exc_tmpl(tmpl_name=tmpl_name) # не вызываем self.drawTemplate, т.к. в потомках его ошибочно переопределяют без параметра draw_wo_login return BasePage.drawTemplate(self, templ=exc, data=[self, data_all], draw_wo_login=True)
def conlog_details(self, dtBeg=None, dtEnd=None, idBase=None, ip=None): """ip - один из ip-адресов разработчика, на которые выдан тикет """ # 0. Обработка входных параметров dtBeg = self.cDateTime(dtBeg) if dtBeg is None: dtBeg = '01.01.2000' dtEnd = self.cStrE(dtEnd) if dtEnd is None: dtEnd = '01.01.2100' else: dtEnd = dtEnd + ' 23:59:59' dtEnd = self.cDateTime(dtEnd) idBase = self.cInt(idBase) ip = self.cStrE(ip) if ip is None: ip = '' # 1. Получить таблицу A без поля WHOS detail_lst = db.dbExecDirect(sql = "select access_stamp" \ " from K_IP_ACCESS_LOG where " + pu.iif(ip, "IP='"+ip+"'", 'IP IS NULL') + " and access_stamp between ? and ? " \ " order by 1 desc", params=(dtBeg, dtEnd), fetch='all', id_base=idBase )['datalist'] return self.drawTemplate(templ=conlog_detail, data=[{ 'detail': detail_lst }])
def find_map_obj(self, full_ref, from_obj=None, from_ref='/'): u"""Поиск объекта маппинга по полному внутреннему URL. full_ref - заданный URL from_obj - от какого объекта начинать рекурсивный поиск по свойствам, None - при поиске от корня from_ref - от какого полного внутреннего URL начинать поиск, '/', '' - при поиске от корня """ from base import BasePage from py_utils import iif found_obj = None # Убираем слэш if full_ref[-1] == '/': full_ref = full_ref[:-1] # w/o slash if from_obj is None: from_obj = self.root if full_ref != from_ref: for ref_name in dir(from_obj): obj = getattr(from_obj, ref_name) if not isinstance(obj, BasePage): continue try: found_obj = self.find_map_obj(full_ref=full_ref, from_obj=obj, from_ref=iif(from_ref == '/', from_ref + ref_name, from_ref + '/' + ref_name)) if found_obj is not None: break except RuntimeError: # бесконечная рекурсия для перестраховки break else: found_obj = from_obj return found_obj
def ajaxTicketAdd(self, develId, idBase, reason, perm, ips): #db_info = self.dbExec(sql="select DB_IP, DB_NAME, DB_LOCATION, SERVER_IP, SERVER_USER, TICKETS_PATH_HOME from ENGINE_GET_BASES_INFO(?)", params=[self.cInt(idBase)], fetch='one') #if db_info is None: # raise TicketsException('Base with ID=%s not found!' % idBase) #dbs = db.get_bases_info(idBase)['dbs'] #if len(dbs) == 0: # raise TicketsException('Base with ID=%s not found!' % idBase) #db_info = dbs[0] #Переводим из строки в объект ips = json.loads(ips) db_info = db.get_bases_info(self.cInt(idBase)) db_location = db_info['DB_LOCATION'] server_user = db_info['SERVER_USER'] server_ip = db_info['SERVER_IP'] db_ip = db.db_ip_to_private(db_info['DB_IP']) db_name = db_info['DB_NAME'] tickets_path_home = db_info['TICKETS_PATH_HOME'] tickets_perm_path_home = db_info['TICKETS_PERM_PATH_HOME'] devel = self.dbExec(sql="select DEVEL_LOGIN, DEVEL_FIO FROM T_DEVEL WHERE DEVEL_ID=?", params=[self.cInt(develId)], fetch='one') if devel is None: raise TicketsException('Developer with ID=%s not exists' % develId) reason = pu.convToWin(reason) devel_login = devel['DEVEL_LOGIN'] devel_fio = devel['DEVEL_FIO'] ticket = dublin.createLink(db_location=db_location, links_path=pu.iif(perm!='0', tickets_perm_path_home, tickets_path_home), login=devel_login, user=server_user, ip=server_ip) #print "55555555555555" #print perm, self.cStrE(perm) #print "55555555555555" conEngine = db.getConEng() group = dbEngine.ConnectionGroup() try: conDb = db.getConDb(self.cInt(idBase)) group.add(conDb) #conEngine.commit() group.add(conEngine) group.begin() try: dic = db.dbExec(sql="select TICKET_ID, GRANT_STAMP from T_ADD(?,?,?,?,?,?)", params=(self.cInt(develId), reason, ticket, self.getUserVar('uid'), self.cInt(idBase), self.cStrE(perm) ), fetch='one', id_system=-1, con=conEngine, conEngine=conEngine ) grant_stamp = formatMxDateTime(dic['GRANT_STAMP'], '%d.%m.%Y %H:%M') for ip in ips: """ip = db.dbExec(sql="select IP from T_DEVEL_IP where ID_DEVEL_IP=?", params=[str(id_ip)], fetch='one', id_system=-1, con=conEngine, conEngine=conEngine )['IP'] """ dic_ip = db.dbExec(sql="select ID_TICKETS_IP from T_ADD_IP(?,?)", params=(dic['TICKET_ID'], str(ip) ), fetch='one', id_system=-1, con=conEngine, conEngine=conEngine ) dic_base_ip = db.dbExecDirect(sql="INSERT INTO K_IP_CHECK (IP, DEVEL_FIO, TICKET_ID, PERM) VALUES(?,?,?,?)", params=(str(ip), devel_fio, dic['TICKET_ID'], self.cStrE(perm) ), fetch='none', id_base=self.cInt(idBase), con=conDb, conEngine=conEngine ) #conEngine.savepoint('A') except: if group.count(): group.rollback() raise else: group.commit() finally: group.disband() #disband the group so that member connections can operate independently again. if dic is not None: pu.send_devel_mail(subject='Тикет выдан', body='Тикет: %s\nIP/port: %s\nБД: %s\nID тикета: %s\nПерманент: %s\nВремя выдачи: %s\nПричина: %s\nРазработчик: %s\nВыдал: %s%s' \ % (ticket, db_ip, db_name, dic['TICKET_ID'], pu.iif(perm!='0', 'Да', 'Нет'), grant_stamp, reason, devel_fio, self.getUserVar('userfio'), signature), id_devel=develId) return self.pyDumps(ext_data={'TICKET_ID': dic['TICKET_ID'], 'GRANT_STAMP': grant_stamp, #'REASON': dic['REASON'], 'DEVEL_FIO': devel_fio, 'TICKET': ticket, 'ADMIN_FIO': self.getUserVar('userfio'), 'DB_IP': db_ip, 'DB_NAME': db_name }) else: return self.pyDumps(ext_data={'TICKET': 'no'})
def loaded_sys_options_js(self): return self.pyDumps(ext_data={'loaded_sys_options': pu.iif(self.loaded_sys_options(), 1, 0)})
def init(basepath): "initialization of web-server" global mappings import hot_conf as hc import conf.engine_conf as cfg import db import cp_utils as cpu import py_utils as pu import system_init as si import api.version as version server = cpu.init_server(basepath=basepath) print "\n FirePy Engine v. " + version.get_full_version() print print "\nInit hot config..." print hc.init_hot_conf(cfg.hot_conf_location) print "\nInit database engine..." print db.init() print "\nReading db version..." (version_from_db, date_from_db) = version.get_version_from_db() db_version_matched = version.check_db_versions(version_from_db) print "\n Db v. %s %s %s" % ( version_from_db, pu.convToConsole('from'), date_from_db) + pu.iif( db_version_matched, ' ...OK', ' ...MISMATCH!!!') if not db_version_matched: print "\nWARNING!!! Db version mismatch!!! Expected %s, really %s" % ( version.accepted_db_version, version.extract_major_minor_db_version(version_from_db)) print # проверка, правильно ли установлены параметры запуска веб-сервера server.check_config() print print "\nReading engine params..." print si.read_engine_params() print print "\nReading bases params..." print si.read_bases_params() print print "\nReading systems params..." print si.read_systems_params() print print "\nMapping of a tree..." print mappings = si.Mappings( basepath, pu.iif('/' in cfg.error_log_file or '\\' in cfg.error_log_file, cfg.error_log_file, basepath + '/log/' + cfg.error_log_file)) root, cntSystems, cntSuccessSystems = mappings.mapAll() print print "TOTAL: %s of %s systems are mounted successfully." % ( cntSuccessSystems, cntSystems) #Close Main Thread connection to db db.main_th_connect_close() print print "\nStarting webserver..." print #may be 2 servers on different ports if cfg.server1: print "Server #1 starts at %s://%s:%s" % ( cfg.server1, cfg.socket_host1, cfg.socket_port1) if cfg.server2: print "Server #2 starts at %s://%s:%s" % ( cfg.server2, cfg.socket_host2, cfg.socket_port2) server.start(root)
def index(self, termnum=None, fti=0, force_browser=0, fmi=0): cherrypy.response.headers["Expires"] = "Mon, 26 Jul 1997 05:00:00 GMT" #Date in the past cherrypy.response.headers["Last-Modified"] = "Mon, 26 Jul 1997 05:00:00 GMT" #always modified cherrypy.response.headers["Cache-Control"] = "no-cache, must-revalidate" # HTTP/1.1 cherrypy.response.headers["Pragma"] = "no-cache" # HTTP/1.0 user_agent = cherrypy.request.headers.get('User-Agent', '') if fti != 0: self.setSesVar('fti', fti) else: #не трогаем fti (оставляем, если был) pass if fmi != 0: self.setSesVar('fmi', fmi) else: #не трогаем fmi (оставляем, если был) pass if cpu.isTerminal(): self.setSesVar('is_terminal', True) # В терминальном урле пишется номер терминала, мы его сохраняем, и когда чистим сессию, не теряем. # При последующем редиректе на cfg.init_url (без передачи termnum), он остаётся if termnum is not None: self.setSesVar('termnum', termnum) else: #не трогаем termnum (оставляем, если был) pass #self.dp('index: termnum=%s, is_terminal=%s' % (self.getSesVar('termnum'), self.getSesVar('is_terminal'))) term = db.dbExec(sql='select * from EQUIP_INFO(?)', params=[self.getSesVar('termnum')], fetch='one', id_system=-1) mes = term['ERROR_MSG'] termusername = term['FIO'] termname = term['EQUIP_NAME'] self.setSesVar('termiduser', term['ID_USER']) self.setSesVar('termusername', termusername) self.setSesVar('termname', termname) return self.drawTemplate(templ=pu.iif(cpu.isMobile(), login_index_mob, login_index_term), data=[{'termname': termname, 'termusername': termusername, 'mes':mes}], draw_wo_login=True) else: self.setSesVar('termiduser', None) self.setSesVar('termusername', None) self.setSesVar('termnum', None) self.setSesVar('termname', None) self.setSesVar('is_terminal', False) # проверим юзер-агент браузера и сравним его с допустимыми parsed_agent = httpagentparser.detect(user_agent) # если юзер-агент не определен if not parsed_agent or not parsed_agent.has_key('browser'): parsed_agent['browser'] = {} parsed_agent['browser']['name'] = 'Неизвестный браузер' parsed_agent['browser']['version'] = '0.0' self.setSesVar('user-agent', parsed_agent['browser']['name'] + ' версия: ' + parsed_agent['browser']['version']) is_allowed_ua = self.allowed_ua(parsed_agent) if not is_allowed_ua: self.setSesVar('user-agent-restricted', True) if not force_browser or not cfg.UA_OTHER_ACCESS: return self.drawTemplate(templ=change_browser, data=[ { 'browser':parsed_agent['browser']['name'], 'version': parsed_agent['browser']['version'], 'ua_other_access':cfg.UA_OTHER_ACCESS, 'baseurl':cherrypy.request.base }], draw_wo_login=True) return self.drawTemplate(templ=login_index, data=[{'langs': cpu.getConfigLangs()}], draw_wo_login=True)
def draw_system_list_term(self, code, termnum): # код завершения смены if code == cfg.TERMINAL_LOGOFF_BARCODE: # запрос на закрытие сессии в RBS mes = sessions.rbs_close_check(self.getSesVar('termiduser')) # не разрешено закрывать сессию if mes: return self.drawTemplate(templ=pu.iif(cpu.isMobile(), login_index_mob, login_index_term), data=[{'termname': self.getSesVar('termname'), 'termusername': self.getSesVar('termusername'), 'mes': mes}], draw_wo_login=True) # получено разрешение из RBS на закрытие сессии # попытка закрыть сессию error_msg, web_session_id = sessions.session_close(uid=self.getSesVar('termiduser'), fio=self.getSesVar('termusername'), equip_kind=pu.iif(cpu.isMobile(), 'M', 'T'), reason=sessions.SES_CLOSE_REASON_EXIT, closed_by=None) # ошибка закрытия сессии if error_msg: cpu.cherrypylog(error_msg, context='APP.SESSIONS') return self.drawTemplate(templ=pu.iif(cpu.isMobile(), login_index_mob, login_index_term), data=[{'termname': self.getSesVar('termname'), 'termusername': self.getSesVar('termusername'), 'mes': error_msg}], draw_wo_login=True) # сессия закрыта успешно termusername = self.getSesVar('termusername') self.exit(redirect=False) return self.drawTemplate(templ=pu.iif(cpu.isMobile(), login_index_mob, login_index_term), data=[{'termname': self.getSesVar('termname'), 'termusername': '', 'mes': 'Сессия пользователя '+termusername+' закрыта'}], draw_wo_login=True) # валидация длины введённого ШК и его целостности if not term_verify_barcode(code): return self.drawTemplate(templ=pu.iif(cpu.isMobile(), login_index_mob, login_index_term), data=[{'termname': self.getSesVar('termname'), 'termusername': self.getSesVar('termusername'), 'mes': 'Отсканирован не ШК пользователя'}], draw_wo_login=True) # структура ШК верна - верифицируем его и определяем пользователя usr = db.dbExec(sql='select * from ENGINE_USER_VERIFY_TERM(?)', params=[code], fetch='one', id_system=-1) if usr['ERROR_CODE']!=0: if usr['ERROR_CODE']==5: # пользователь найден, а ШК - нет # сверяем дату генерации ШК в БД и отсканированного ШК msg_check_barcode_date = check_barcode_date(code, usr['BARCODE_OUT']) if msg_check_barcode_date: return self.drawTemplate(templ=pu.iif(cpu.isMobile(), login_index_mob, login_index_term), data=[{'termusername': usr['FIO'], #'termusername': self.getSesVar('termusername'), 'termname': self.getSesVar('termname'), 'mes': msg_check_barcode_date }], draw_wo_login=True) # валидация длины ШК в БД и его целостности if not term_verify_barcode(usr['BARCODE_OUT']): return self.drawTemplate(templ=pu.iif(cpu.isMobile(), login_index_mob, login_index_term), data=[{'termusername':usr['FIO'], #'termusername': self.getSesVar('termusername'), 'termname': self.getSesVar('termname'), 'mes': 'Испорчен ШК в базе данных. Обратитесь в службу поддержки!'}], draw_wo_login=True) # неизвестная ошибка в ШК return self.drawTemplate(templ=pu.iif(cpu.isMobile(), login_index_mob, login_index_term), data=[{'termusername':usr['FIO'], #'termusername': self.getSesVar('termusername'), 'termname': self.getSesVar('termname'), 'mes': 'Неизвестная ошибка в ШК. Обратитесь в службу поддержки!'}], draw_wo_login=True) else: #2 - 'Пользователь не заведён в системе!' или другая будущая ошибка return self.drawTemplate(templ=pu.iif(cpu.isMobile(), login_index_mob, login_index_term), data=[{'termname': self.getSesVar('termname'), 'termusername': self.getSesVar('termusername'), 'mes': usr['ERROR_MSG']}], draw_wo_login=True) if getattr(cfg, 'SKUD_INTEGRATION', False) and \ (getattr(cfg, 'SKUD_CHECK_MOBILE', False) and cpu.isMobile() or getattr(cfg, 'SKUD_CHECK_TSD', False) and cpu.isTSD()): allow = db.dbExecDirect(sql='select ALLOW from %s(?)' % cfg.SKUD_MAJOR_DB_ACCESS_PROC, params=[usr['ID_USER']], fetch='one', id_base=db.getIdMajorDb())['ALLOW'] if not allow: if cpu.isTSD(): return cpu.goToError(_('Доступ запрещён по данным СКУД!')) else: return self.exception_inner(tmpl_name='exception_skud_access_mob', data={'userfio': usr['FIO']}) # заказан ли проброс для этого вида оборудования в конфиге probros = pu.iif(cpu.isMobile(), getattr(cfg, 'sessions_forward_to_last_iface_mob', None), getattr(cfg, 'sessions_forward_to_last_iface_term', None)) if probros: # читаем данные последней сессии error_msg, go_url, ses_info = sessions.session_last_session_info(uid=usr['ID_USER'], fio=usr['FIO'], equip_kind=pu.iif(cpu.isMobile(), 'M', 'T') ) # ошибка получения информации о последней сессии if error_msg: cpu.cherrypylog(error_msg, context='APP.SESSIONS') probros = False # открываем сессию old_web_session_id, error_msg = sessions.session_open(uid=usr['ID_USER'], fio=usr['FIO'], equip_kind=pu.iif(cpu.isMobile(), 'M', 'T'), termnum=termnum) # ошибка открытия сессии if error_msg: cpu.cherrypylog(error_msg, context='APP.SESSIONS') return self.drawTemplate(templ=pu.iif(cpu.isMobile(), login_index_mob, login_index_term), data=[{'termname': self.getSesVar('termname'), 'termusername': usr['FIO'], 'mes': error_msg}], draw_wo_login=True) # удаляем старую web-сессию, если она есть if old_web_session_id: sessions.session_delete_old_web_session(old_web_session_id) # залогинились #print "draw_system_list_term: id_user=%s, fio=%s, barcode=%s" %( usr['ID_USER'], self.df(usr['FIO']), usr['BARCODE_OUT']) # заполняем переменные сессии юзера create_user_session_class(login=usr['LOGIN'], uid=usr['ID_USER'], userfio=usr['FIO'], email=usr['EMAIL'], phonenumber=usr['PHONENUMBER'], layer_id=usr['LAYER_ID'], locale=usr['LANG_CODE'] or self.getSesVar('locale'), is_superadmin=usr['IS_SUPERADMIN']) self.setSesVar('termiduser', usr['ID_USER']) self.setSesVar('termusername', usr['FIO']) # далее реализуем проброс # проброс в зависимости от настроек конфиругации и наличия последней сохранённой сессии if probros and go_url: # если error_msg пусто, то go_url заполнено - переходим в него raise cherrypy.HTTPRedirect(go_url) else: # иначе - анализируем # получаем доступные системы нулевого уровня, сортируя по cfg.systems_order systems = get_user_systems(uid=self.getUserVar("uid"), higher=None, recurse=0, use_layers=None) # если юзер не имеет прав ни на одну из систем нулевого уровня if len(systems['datalist'])==0: return self.drawTemplate(templ=pu.iif(cpu.isMobile(), login_index_mob, login_index_term),data=[{'mes':'Пользователь не имеет прав ни на одну систему'}], draw_wo_login=True) # если у юзера есть право на KURSTERM или WMSMOBILE и список систем в нём непуст, то перебрасываем в KURSTERM или WMSMOBILE if cpu.isMobile(): # если у юзера есть право на WMSMOBILE if getattr(cfg, 'MOBILE_link', None) in self.getUserVar('granted_system_refs'): # получить id_system для системы WMSMOBILE MOBILE_id_system = si.find_id_system_by_full_ref_name(cfg.MOBILE_link) #TERMINAL_id_system=db.dbExec(sql='select ID_SYSTEM from ENGINE_FIND_SYSTEM_BY_FULL_REF(?)', # params=[cfg.TERMINAL_link], fetch='one', id_system=-1)['ID_SYSTEM'] # получить список доступных юзеру подсистем в системе WMSMOBILE mobile_subsystems = get_user_systems(uid=self.getUserVar("uid"), higher=MOBILE_id_system, recurse=0, use_layers=None) # если список доступных юзеру подсистем в системе WMSMOBILE содержит одну запись(возможно, OLDTERM), то перебрасываем в неё if len(mobile_subsystems['datalist']) == 1: #raise cherrypy.HTTPRedirect(terminal_subsystems['datalist'][0]['FULL_REF_NAME']+'/?id_system='+ str(terminal_subsystems['datalist'][0]['ID_SYSTEM'])) raise cherrypy.HTTPRedirect(mobile_subsystems['datalist'][0]['FULL_REF_NAME']) # иначе перебрасываем в WMSMOBILE else: #raise cherrypy.HTTPRedirect(cfg.TERMINAL_link+'/?id_system='+ str(TERMINAL_id_system)) raise cherrypy.HTTPRedirect(cfg.MOBILE_link) else: # если у юзера есть право на KURSTERM if getattr(cfg, 'TERMINAL_link', None) in self.getUserVar('granted_system_refs'): # получить id_system для системы KURSTERM TERMINAL_id_system = si.find_id_system_by_full_ref_name(cfg.TERMINAL_link) #TERMINAL_id_system=db.dbExec(sql='select ID_SYSTEM from ENGINE_FIND_SYSTEM_BY_FULL_REF(?)', # params=[cfg.TERMINAL_link], fetch='one', id_system=-1)['ID_SYSTEM'] # получить список доступных юзеру подсистем в системе KURSTERM terminal_subsystems = get_user_systems(uid=self.getUserVar("uid"), higher=TERMINAL_id_system, recurse=0, use_layers=None) # если список доступных юзеру подсистем в системе KURSTERM содержит одну запись(возможно, OLDTERM), то перебрасываем в неё if len(terminal_subsystems['datalist']) == 1: #raise cherrypy.HTTPRedirect(terminal_subsystems['datalist'][0]['FULL_REF_NAME']+'/?id_system='+ str(terminal_subsystems['datalist'][0]['ID_SYSTEM'])) raise cherrypy.HTTPRedirect(terminal_subsystems['datalist'][0]['FULL_REF_NAME']) # иначе перебрасываем в KURSTERM else: #raise cherrypy.HTTPRedirect(cfg.TERMINAL_link+'/?id_system='+ str(TERMINAL_id_system)) raise cherrypy.HTTPRedirect(cfg.TERMINAL_link) # если у юзера есть права более, чем на 1 систему - рисуем список систем на выбор if len(systems['datalist'])>1: #return self.drawTemplate(templ=choose_your_destiny,data=[systems]) return self.drawTemplate(templ=pu.iif(cpu.isMobile(), subsystem_list_mob, subsystem_list_term), data=[systems, {'system_name': _('Выберите систему')}]) # если у юзера есть право только на одну систему, то перебрасываем в неё if len(systems['datalist'])==1: #self.setSesVar("id_system",systems['datalist'][0]['ID_SYSTEM']) #raise cherrypy.HTTPRedirect(systems['datalist'][0]['FULL_REF_NAME']+'/?id_system='+ str(self.getSesVar("id_system"))) #print "if len(systems['datalist'])==1:" #raise cherrypy.HTTPRedirect(systems['datalist'][0]['FULL_REF_NAME']+'/?id_system='+ str(systems['datalist'][0]['ID_SYSTEM'])) raise cherrypy.HTTPRedirect(systems['datalist'][0]['FULL_REF_NAME'])
def ajaxTicketDel(self, ticketId): #Ищем idBase idBase = self.dbExec(sql="select ID_BASE from T_TICKETS where TICKET_ID=?", params=[self.cInt(ticketId)], fetch='one')['ID_BASE'] #Мультибазная транзакция conEngine = db.getConEng() group = dbEngine.ConnectionGroup() try: conDb = db.getConDb(idBase) group.add(conDb) #conEngine.commit() group.add(conEngine) group.begin() try: dic = db.dbExec(sql="select TICKET, DELETED_TIME, DEVEL_ID, ID_BASE, PERM from T_MARK_DEL(?)", params=[self.cInt(ticketId)], fetch='one', id_system=-1, con=conEngine, conEngine=conEngine ) db.dbExecDirect(sql="delete from K_IP_CHECK where TICKET_ID=?", params=[self.cInt(ticketId)], fetch='none', id_base=idBase, con=conDb, conEngine=conEngine ) except: if group.count(): group.rollback() raise else: group.commit() finally: group.disband() #disband the group so that member connections can operate independently again. if dic is not None: deleted_time = formatMxDateTime(dic['DELETED_TIME'], format='%H:%M', sformatFrom='%H:%M:%S') ticket = dic['TICKET'] idBase = dic['ID_BASE'] perm = dic['PERM'] #db_info = self.dbExec(sql="select DB_IP, DB_NAME, SERVER_IP, SERVER_USER from ENGINE_GET_BASES_INFO(?)", params=[self.cInt(idBase)], fetch='one') #if db_info is None: # raise TicketsException('Base with ID=%s not found!' % idBase) #dbs = db.get_bases_info(idBase)['dbs'] #if len(dbs) == 0: # raise TicketsException('Base with ID=%s not found!' % idBase) #db_info = dbs[0] db_info = db.get_bases_info(idBase) server_user = db_info['SERVER_USER'] server_ip = db_info['SERVER_IP'] db_ip = db.db_ip_to_private(db_info['DB_IP']) db_name = db_info['DB_NAME'] dublin.dropLink(link_location=ticket, user=server_user, ip=server_ip) pu.send_devel_mail(subject='Тикет удалён', body='Тикет: %s\nIP/port: %s\nБД: %s\nID тикета: %s\nПерманент: %s\nВремя удаления: %s%s' \ % (ticket, db_ip, db_name, ticketId, pu.iif(perm, 'Да', 'Нет'), deleted_time, signature), id_devel=dic['DEVEL_ID']) return self.pyDumps(ext_data={'TICKET': ticket, 'DELETED_TIME': deleted_time}) else: return self.pyDumps(ext_data={'TICKET': 'no', 'DELETED_TIME': 'no'})
def conlog_conlog(self, develId=None, dtBeg=None, dtEnd=None, idBase=None, ip=None): """ip - один из ip-адресов разработчика, на которые выдан тикет """ #import time #time_beg=time.time() # 0. Обработка входных параметров develId = self.cInt(develId) dtBeg = self.cDateTime(dtBeg) if dtBeg is None: dtBeg = '01.01.2000' dtEnd = self.cStrE(dtEnd) if dtEnd is None: dtEnd = '01.01.2100' else: dtEnd = dtEnd + ' 23:59:59' dtEnd = self.cDateTime(dtEnd) idBase = self.cInt(idBase) ip = self.cStrE(ip) if ip is None: ip = '' # 1. Получить таблицу A без поля WHOS conlog_lst_ro = db.dbExecDirect(sql = "select ip, max(access_stamp) last_access, count(*) cnt" \ " from K_IP_ACCESS_LOG where " + pu.iif(ip, "IP='"+ip+"'", '1=1') + " and access_stamp between ? and ? " \ " group by ip " \ " order by 3 desc ", params=(dtBeg, dtEnd), fetch='all', id_base=idBase )['datalist'] # не r/o-набор данных с заполненным полем WHOS conlog_lst = [] # По каждой записи (cur_ip) таблицы A: # Получить список devels = [{'DEVEL_ID': 1585, 'DEVEL_FIO': 'Робот'}, {...}, ...] по тикетам, которые были активны в момент коннекта for dic_ro in conlog_lst_ro: devels = [] cur_ip = dic_ro['IP'] cnt = dic_ro['cnt'] # Большие не запрашиваем if cnt > 400: #добавляем строку в conlog_lst и заполняем поле "кто" '???' #копируем текущую строку conlog_lst_ro в conlog_lst dic = {} #по столбцам for key, val in dic_ro.items(): dic[key] = val #WHOS dic['WHOS'] = "..." conlog_lst.append(dic) else: devels = self.get_devels(ip=cur_ip, dtBeg=dtBeg, dtEnd=dtEnd, idBase=idBase) # Если есть фильтр по "кто" и среди devels нет этого "кто", то исключаем строку из таблицы A if develId and develId not in map(lambda d: d['DEVEL_ID'], devels): # просто строку не включаем pass # иначе добавляем строку в conlog_lst и заполняем поле "кто" списком всех DEVEL_FIO else: #копируем текущую строку conlog_lst_ro в conlog_lst dic = {} #по столбцам for key, val in dic_ro.items(): dic[key] = val #WHOS dic['WHOS'] = reduce( lambda all_s, d: all_s + ', ' + d['DEVEL_FIO'], devels, '')[2:] conlog_lst.append(dic) conlog_lst = {'datalist': conlog_lst} #print "conlog_conlog Exec Time: ", time.time()-time_beg return self.drawTemplate(templ=conlog_master, data=[conlog_lst])