# coding: utf-8 ''' @author: d.bozhenko ''' import json from java.util import ArrayList try: from ru.curs.showcase.core.jython import JythonDTO from ru.curs.showcase.core.selector import ResultSelectorData from ru.beta2.extra.gwt.ui.selector.api import DataRecord from ru.curs.showcase.security import SecurityParamsFactory except: from ru.curs.celesta.showcase import JythonDTO from ru.curs.celesta import CelestaException from ru.curs.celesta.showcase.utils import XMLJSONConverter from security.functions import Settings, getUsersFromAuthServer, id_generator import hashlib from common.numbersseries.getNextNo import getNextNoOfSeries from common.sysfunctions import tableCursorImport from security._security_orm import loginsCursor from security._security_orm import subjectsCursor # Процедуры карточки и сохранения для всех четырёх режимов работы гранулы def cardData(context, main=None, add=None, filterinfo=None, session=None, elementId=None): settings = Settings() session = json.loads(session)['sessioncontext'] logins = loginsCursor(context) subjects = subjectsCursor(context) isEmployees = settings.isEmployees() # описана ли таблица сотрудников в настройках? if isEmployees: # Если да, получаем наименование таблицы, импортируем курсор, создаём экземпляр курсора сотрудников employeesGrain = settings.getEmployeesParam("employeesGrain") employeesTable = settings.getEmployeesParam("employeesTable") employeesId = settings.getEmployeesParam("employeesId") # название поля с первичным ключом employeesName = settings.getEmployeesParam("employeesName") # название поля с именем employeesCursor = tableCursorImport(employeesGrain, employeesTable) employees = employeesCursor(context) subjectId = "" subjectName = "" empId = "" empName = "" if 'currentRecordId' in session['related']['gridContext']: currId = session['related']['gridContext']['currentRecordId'] currIdSid = "" if settings.loginIsSubject() and settings.isUseAuthServer(): # в данном режиме Id записи грида - sid+username. делано, чтобы достать сид в карточке, # не перелопачивая весь xml пользователй. currIdSid = json.loads(currId)[1] currId = json.loads(currId)[0] if logins.tryGet(currId) and add <> 'add': if subjects.tryGet(logins.subjectId): subjectId = subjects.sid subjectName = subjects.name if isEmployees: if employees.tryGet(subjects.employeeId): empId = getattr(employees, employeesId) empName = getattr(employees, employeesName) if add == 'add': xformsdata = {"schema":{"@xmlns":"", "user":{"@sid": "", "@password": id_generator(), "@userName": "", "@subjectId":"", "@subjectName":"", "@employeeId":"", "@employeeName":"", "@isAuthServer":unicode(settings.isUseAuthServer()).lower(), "@loginIsSubject":unicode(settings.loginIsSubject()).lower(), "@add":add, "@isEmployees":unicode(isEmployees).lower(), "@key":unichr(9911) # символ ключа, например. Уже не нужен, в иконку вставляется картинка. } } } if settings.loginIsSubject(): # если логины тождественны субъектам, при открытии карточки генерится sid sid = getNextNoOfSeries(context, 'subjects') + id_generator() # последнее слагаемое сделано, чтобы sid # нельзя было просто подобрать. xformsdata["schema"]["user"]["@subjectId"] = sid xformsdata["schema"]["user"]["@sid"] = sid elif add == 'edit' and settings.isUseAuthServer(): # Редактирование в случае получения пользователей из mellophone xformsdata = {"schema":{"user":{"@sid": currIdSid, "@password": "", "@userName": currId, "@subjectId":subjectId, "@subjectName":subjectName, "@employeeId":empId, "@employeeName":empName, "@isAuthServer":unicode(settings.isUseAuthServer()).lower(), "@loginIsSubject":unicode(settings.loginIsSubject()).lower(), "@add":"", "@isEmployees":unicode(isEmployees).lower(), "@key":unichr(9911)} } } elif add == 'edit': # Редактирование в случае получения пользователей из таблицы logins logins.get(currId) xformsdata = {"schema":{"user":{"@sid": logins.subjectId, "@password": "", "@userName": logins.userName, "@subjectId":subjectId, "@subjectName":subjectName, "@employeeId":empId, "@employeeName":empName, "@isAuthServer":unicode(settings.isUseAuthServer()).lower(), "@loginIsSubject":unicode(settings.loginIsSubject()).lower(), "@add":add, "@isEmployees":unicode(isEmployees).lower() } } } xformssettings = {"properties":{"event":{"@name":"single_click", "@linkId": "1", "action":{"#sorted":[{"main_context": "current"}, {"datapanel": {"@type": "current", "@tab": "current", "element":{"@id":"usersGrid", "add_context": ""} } }]} } } } return JythonDTO(XMLJSONConverter.jsonToXml(json.dumps(xformsdata)), XMLJSONConverter.jsonToXml(json.dumps(xformssettings))) def cardDataSave(context, main=None, add=None, filterinfo=None, session=None, elementId=None, xformsdata=None): u'''Функция сохранения карточки редактирования содержимого справочника ролей. ''' settings = Settings() logins = loginsCursor(context) subject = subjectsCursor(context) content = json.loads(xformsdata)["schema"]["user"] if not settings.isUseAuthServer(): # пользователи берутся из logins if add == 'edit' and content["@password"] == '': # если пароль при редактировании не заполнен, сохраняем в курсоре старый пароль из базы loginsOld = loginsCursor(context) currId = json.loads(session)['sessioncontext']['related']['gridContext']['currentRecordId'] loginsOld.get(currId) logins.password = loginsOld.password else: # иначе зашифровываем пароль из карточки pass_hash = hashlib.sha1() # Объект типа hash pass_hash.update(content["@password"]) # Записываем в него текущий пароль из карточки logins.password = pass_hash.hexdigest() # Выполняем hash функцию, записываем результат в курсор. logins.userName = content["@userName"] if content["@subjectId"] == "": # если subjectId из карточки пуст, записываем в базу null logins.subjectId = None else: logins.subjectId = content["@subjectId"] if settings.loginIsSubject(): # если loginIsSubject, cохраняем сначала subject, потом login subject.sid = content["@subjectId"] subject.name = content["@userName"] if content["@employeeId"] == '': # если employeeId из карточки пуст (сотрудник не выбран), записываем в базу null subject.employeeId = None else: subject.employeeId = content["@employeeId"] # сохранение subject if add == 'add' and subject.canInsert() and subject.canModify(): if not subject.tryInsert(): subjectOld = subjectsCursor(context) subjectOld.get(content["@subjectId"]) subject.recversion = subjectOld.recversion subject.update() elif add == 'add' and logins.canInsert(): subject.insert() elif add == 'edit' and subject.canModify(): subjectOld = subjectsCursor(context) subjectOld.get(content["@subjectId"]) subject.recversion = subjectOld.recversion subject.update() else: raise CelestaException(u"Недостаточно прав для данной операции!") # сохранение login if add == 'add' and logins.canInsert() and logins.canModify(): if not logins.tryInsert(): logins.update() elif add == 'add' and logins.canInsert(): logins.insert() elif add == 'edit' and logins.canModify(): loginsOld = loginsCursor(context) loginsOld.get(content["@userName"]) logins.recversion = loginsOld.recversion logins.update() else: raise CelestaException(u"Недостаточно прав для данной операции!") else: # пользователи берутся из mellophone if logins.tryGet(content["@userName"]): # если запись с данным userName уже есть в таблице logins (Подробнее см. ниже) if settings.loginIsSubject(): # если логины и субъекты тождественны if not subject.tryGet(logins.subjectId): subject.sid = content["@sid"] if content["@employeeId"] == '': subject.employeeId = None else: subject.employeeId = content["@employeeId"] subject.name = content["@userName"] logins.subjectId = subject.sid # сохранение subject. Запись в logins уже есть if subject.canInsert() and subject.canModify(): if not subject.tryInsert(): subjectOld = subjectsCursor(context) subjectOld.get(content["@subjectId"]) subject.recversion = subjectOld.recversion subject.update() elif subject.canModify(): subjectOld = subjectsCursor(context) subjectOld.get(content["@subjectId"]) subject.recversion = subjectOld.recversion subject.update() else: raise CelestaException(u"Недостаточно прав для данной операции!") else: # Если субъекты тождественны сотрудникам, записываем subjectId в logins.subjectId # то есть, просто привязываем logins к subjects if content["@subjectId"] == "": logins.subjectId = None else: logins.subjectId = content["@subjectId"] # обновление logins if logins.canModify(): logins.update() else: raise CelestaException(u"Недостаточно прав для данной операции!") else: # пользователя нет в logins if settings.loginIsSubject(): # если loginIsSubject, cохраняем сначала subject, потом login if content["@employeeId"] == '': logins.subjectId = None else: subject.employeeId = content["@employeeId"] subject.sid = content["@sid"] subject.name = content["@userName"] logins.subjectId = subject.sid if subject.canInsert() and subject.canModify(): if not subject.tryInsert(): subjectOld = subjectsCursor(context) subjectOld.get(content["@subjectId"]) subject.recversion = subjectOld.recversion subject.update() elif subject.canInsert(): subject.insert() else: raise CelestaException(u"Недостаточно прав для данной операции!") else: if content["@subjectId"] == "": logins.subjectId = None else: logins.subjectId = content["@subjectId"] # В случае, когда пользователи берутся из mellophone, и к пользователю делается привязка, # (<employees> к logins-subjects или <employees>-subjects к logins) # делается запись в logins logins.userName = content["@userName"] logins.password = "" if logins.canInsert(): logins.insert() else: raise CelestaException(u"Недостаточно прав для данной операции!") def subjectsCount(context, main=None, add=None, filterinfo=None, session=None, params=None, curvalue=None, startswith=None): u'''Функция count для селектора выбора ролей. ''' subjects = subjectsCursor(context) subjects.setFilter('name', """@%s'%s'%%""" % ("%"*(not startswith), curvalue.replace("'", "''"))) count = subjects.count() return ResultSelectorData(None, count) def subjectsList(context, main=None, add=None, filterinfo=None, session=None, params=None, curvalue=None, startswith=None, firstrecord=None, recordcount=None): u'''Функция list для селектора выбора ролей. ''' subjects = subjectsCursor(context) subjects.setFilter('name', """@%s'%s'%%""" % ("%"*(not startswith), curvalue.replace("'", "''"))) subjects.orderBy('name') subjects.limit(firstrecord, recordcount) recordList = ArrayList() for subjects in subjects.iterate(): rec = DataRecord() rec.setId(unicode(subjects.sid)) rec.setName(subjects.name) recordList.add(rec) return ResultSelectorData(recordList, 0) def employeesCount(context, main=None, add=None, filterinfo=None, session=None, params=None, curvalue="", startswith=False): settings = Settings() employeesGrain = settings.getEmployeesParam("employeesGrain") employeesTable = settings.getEmployeesParam("employeesTable") # employeesId=getEmployeesParam("employeesId") employeesName = settings.getEmployeesParam("employeesName") employeesCursor = tableCursorImport(employeesGrain, employeesTable) employees = employeesCursor(context) employees.setFilter(employeesName, "@%s'%s'%%" % ("%"*(not startswith), curvalue.replace("'", "''"))) count = employees.count() # raise Exception(count) return ResultSelectorData(None, count) def employeesList(context, main=None, add=None, filterinfo=None, session=None, params=None, curvalue="", startswith=False, firstrecord=0, recordcount=None): u'''Функция list селектора типа элемента. ''' settings = Settings() # raise Exception(curvalue) recordList = ArrayList() employeesGrain = settings.getEmployeesParam("employeesGrain") employeesTable = settings.getEmployeesParam("employeesTable") employeesId = settings.getEmployeesParam("employeesId") employeesName = settings.getEmployeesParam("employeesName") employeesCursor = tableCursorImport(employeesGrain, employeesTable) employees = employeesCursor(context) employees.setFilter(employeesName, "@%s'%s'%%" % ("%"*(not startswith), curvalue.replace("'", "''"))) employees.orderBy(employeesName) employees.limit(firstrecord, recordcount) for employees in employees.iterate(): rec = DataRecord() rec.setId(getattr(employees, employeesId)) rec.setName(getattr(employees, employeesName)) recordList.add(rec) return ResultSelectorData(recordList, 0) # Триггеры для автоматического добавления, редактирования, удаления записей в subjects при редактировании таблицы сотрудников. # Добавляются в случае, если субъекты тождественны сотрудникам. def employeesSubjectsPostInsert(rec): # Триггер добавляется только в случае loginEqualSubject = "false" settings = Settings() context = rec.callContext() employeesId = settings.getEmployeesParam("employeesId") employeesName = settings.getEmployeesParam("employeesName") sid = getNextNoOfSeries(context, 'subjects') + id_generator() subjects = subjectsCursor(context) subjects.sid = sid subjects.name = getattr(rec, employeesName) subjects.employeeId = getattr(rec, employeesId) if subjects.canInsert() and subjects.canModify(): if not subjects.tryInsert(): subjects.update() elif subjects.canInsert(): subjects.insert() def employeesSubjectsPostUpdate(rec): # Триггер добавляется только в случае loginEqualSubject = "false" settings = Settings() context = rec.callContext() employeesId = settings.getEmployeesParam("employeesId") employeesName = settings.getEmployeesParam("employeesName") subjects = subjectsCursor(context) subjects.setRange("employeeId", getattr(rec, employeesId)) if subjects.tryFirst(): # and subjects.count()==1: subjects.name = getattr(rec, employeesName) if subjects.canModify(): subjects.update() def employeesSubjectsPreDelete(rec): # Триггер добавляется только в случае loginEqualSubject = "false" settings = Settings() context = rec.callContext() employeesId = settings.getEmployeesParam("employeesId") subjects = subjectsCursor(context) subjects.setRange("employeeId", getattr(rec, employeesId)) if subjects.canDelete(): subjects.deleteAll()