Проверка подлинности СНИЛС через сервис СМЭВ без использования RS-Connect
Скачать (rar-файл; Размер - 6145)Обсудить в форуме
Описание
Проверка подлинности СНИЛС через сервис СМЭВ без использования RS-Connect
Текст примера
/* Проверка подлинности СНИЛС через сервис СМЭВ без использования RS-Connect Будет работать, если у вас работает обмен с ГИС-ГМП через "Электронный обмен" Васильев Д.В., КБ "РИАЛ-КРЕДИТ" декабрь 2016 Для использования макроса необходим пользовательский макрос ldmklbr.mac, есть в "Примеры/Библиотеки разработчика/Динамическое создание диалогов из макроса средствами языка RSL" */ import Bankinter, rsexts, rslxml, txml, txmlelem, tdocxml, smev_send, smev_xsd_check; import RsbCryptoInter; import no_common; import smev_gis_gmp_notice_cmn; // далее идёт включение "пользовательского" макроса import "..\\mac\\userb\\ldmklbr.mac"; const REG_PATH_SM_1 = "ЭЛЕКТРОННЫЙ ОБМЕН\\ГИС ГМП\\ИДЕНТИФИКАТОР УЗЛА СМЭВ"; const REG_PATH_SM_2 = "ЭЛЕКТРОННЫЙ ОБМЕН\\ГИС ГМП\\ИДЕНТИФИКАТОР ИНИЦИАТОРА В СМЭВ"; const REG_PATH_SM_3 = "BANK_INI\\ОБЩИЕ ПАРАМЕТРЫ\\ПЕРЕМЕННЫЕ\\TIMEZONE"; const REG_PATH_SM_5 = "ЭЛЕКТРОННЫЙ ОБМЕН\\ГИС ГМП\\ИДЕНТИФИКАТОР ЕГПУ В СМЭВ"; const REG_PATH_SM_6 = "ЭЛЕКТРОННЫЙ ОБМЕН\\ГИС ГМП\\РЕЖИМ ОН-ЛАЙН"; const REG_PATH_SM_7 = "ЭЛЕКТРОННЫЙ ОБМЕН\\ГИС ГМП\\КОПИЯ ФАЙЛА"; const REG_PATH_SM_8 = "ЭЛЕКТРОННЫЙ ОБМЕН\\ГИС ГМП\\АДРЕС СМЭВ"; const REG_PATH_SM_9 = "ЭЛЕКТРОННЫЙ ОБМЕН\\ГИС ГМП\\ЭЦП"; const REG_PATH_SM_10 = "ЭЛЕКТРОННЫЙ ОБМЕН\\ГИС ГМП\\ДИРЕКТОРИЯ ФАЙЛОВ ИЗ СМЭВ"; const REG_PATH_SM_12 = "ЭЛЕКТРОННЫЙ ОБМЕН\\ГИС ГМП\\ИДЕНТИФИКАТОР УЧАСТНИКА В ТОФК"; const КодУчастникаСМЭВ = "553001771"; const НаименованиеБанка= "Коммерческий банк РИАЛ-КРЕДИТ (ООО)"; private var crypto_api: CRslCryptoApi; private var СНИЛС_Фамилия, СНИЛС_Имя, СНИЛС_Отчество, СНИЛС_Пол, СНИЛС_ДРожд, СНИЛС_СНИЛС; //======================================================== // Процедура возвращает номер позиции последнего вхождения // строки string2 в строке string1 или 0, // если строка string2 не найдена в string1 //======================================================== macro LastIndex(string1, string2) var k = 1, k1 = 0; while (k > 0) k = index(string1, string2); string1 = substr(string1, k + 1); if (k > 0) k1 = k1 + k end; end; return k1 end; private macro DateToDDMMYYYY(d) var dd, mm, yyyy, dtstr = ""; DateSplit(d, dd, mm, yyyy); if (dd < 10) dtstr = dtstr + "0" + string(dd); else dtstr = dtstr + string(dd); end; if (mm < 10) dtstr = dtstr + "-" + "0" + string(mm); else dtstr = dtstr + "-" + string(mm); end; return dtstr + "-" + string(yyyy); end; class TCreateMessage( _dir:string, _date_form:date, _time_form:time, _recipient:string, _recipient_name:string ) private var m_objXML = TXML(not IsStandAlone(), "UTF-8"); private var m_objCon = CWebInterface(); private var m_root; private var m_sroot; private var m_proot; private var m_identifier:string = ""; private const m_dir_out_setting = _dir; private var m_file_name_creator:SMEVFileName; private var m_notif:string = ""; private var m_uid:string = ""; private var m_xsd = TSmevXsdCheck(); var m_timestamp; var m_date_form = _date_form; var m_time_form = _time_form; var m_rec:string = _recipient; var m_rec_name:string = _recipient_name; macro GetMode():bool var mode = false, err; GetRegistryValue(REG_PATH_SM_6, V_BOOL, mode, err); return mode; end; macro GetDSMode():bool var mode = false, err; GetRegistryValue(REG_PATH_SM_9, V_BOOL, mode, err); return mode; end; macro GetFileCopy():bool var value = false, err; GetRegistryValue(REG_PATH_SM_7, V_BOOL, value, err); return value; end; macro GetAddressSMEV():string var value:string = "", err; //GetRegistryValue(REG_PATH_SM_8, V_STRING, value, err); //return value; return "http://oraas.rt.ru:7777/gateway/services/SID0003822"; end; macro GetNMSenderIdentifier():String var value:string = "", err; GetRegistryValue(REG_PATH_SM_12, V_STRING, value, err); return value; end; private var OnlineMode:bool = GetMode(); private var Address:string = GetAddressSMEV(); macro CreateAttr( name:string, value ) var node = m_objXML.m_doc.createAttribute(name); node.value = value; m_root.setAttributeNode(node); end; macro GetUID() : string var id, err; GetRegistryValue(REG_PATH_SM_1, V_STRING, id, err); if ( err ) id = ""; end; return id; end; macro GetInitiator() : string var id, err; GetRegistryValue(REG_PATH_SM_2, V_STRING, id, err); if ( err ) id = ""; end; return id; end; macro GetTimezone() : string var zone, err; GetRegistryValue(REG_PATH_SM_3, V_STRING, zone, err); if ( err ) zone = ""; end; return zone; end; macro CreateError(recv : string) m_notif = m_notif + GenXmlErrMsg(recv) + "\n"; end; macro CreateErrorXSD( recv ) m_notif = m_notif + "!Нарушение формата: " + recv + "\n"; end; macro CreateBodyMessage():integer end; macro CreateSMEV():integer var err = 0, id; var StrOut:string = ""; var m_header, m_mes, m_post; m_header = m_objXML.m_doc.appendChild(m_objXML.m_doc.createElement("soapenv:Envelope")); m_root = m_header; CreateAttr("xmlns:soapenv", "http://schemas.xmlsoap.org/soap/envelope/"); m_sroot = m_root.appendChild(m_objXML.m_doc.createElement("soapenv:Header")); var _hour:integer = 0; var _min:integer = 0; var _sec:integer = 0; var _msec; TimeSplit( m_time_form, _hour, _min, _sec, _msec); _msec = LZ( _msec, 3 ); m_timestamp = DtTm( m_date_form, Time(_hour, _min, _sec, _msec) ); m_timestamp = valtoxml(m_timestamp); m_timestamp = m_timestamp + "." + _msec + GetTimezone(); m_root = m_header.appendChild(m_objXML.m_doc.createElement("soapenv:Body")); CreateAttr("xmlns:wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"); CreateAttr("wsu:Id" , "body"); m_mes = m_root.appendChild(m_objXML.m_doc.createElement("snil:SnilsValidationRequest")); m_root = m_mes; CreateAttr("xmlns:snil", "http://snils-validation.skmv.rstyle.com"); CreateAttr("xmlns:pfr", "http://pfr.skmv.rstyle.com"); CreateAttr("xmlns:rev", "http://smev.gosuslugi.ru/rev120315"); m_proot = m_mes.appendChild(m_objXML.m_doc.createElement("rev:Message")); m_sroot = m_proot.appendChild(m_objXML.m_doc.createElement("rev:Sender")); m_root = m_sroot.appendChild(m_objXML.m_doc.createElement("rev:Code")); m_root.text = КодУчастникаСМЭВ; m_root = m_sroot.appendChild(m_objXML.m_doc.createElement("rev:Name")); ToUTF8(StrUpr(НаименованиеБанка), StrOut); m_root.text = StrOut; m_sroot = m_proot.appendChild(m_objXML.m_doc.createElement("rev:Recipient")); m_root = m_sroot.appendChild(m_objXML.m_doc.createElement("rev:Code")); m_root.text = "PFRF01001"; m_root = m_sroot.appendChild(m_objXML.m_doc.createElement("rev:Name")); //ToUTF8("Пенсионный фонд РФ", StrOut); - почему-то перекодировка такой строки не отрабатывает, формируем по-другому, сами m_root.text = "" + StrFor(128+(15)) + StrFor(128+(37)) + StrFor(128+(45)) + StrFor(128+(97)) + StrFor(128+(40)) + StrFor(128+(46)) + StrFor(128+(45)) + StrFor(128+(45)) + StrFor(128+(107)) + StrFor(128+(41)) + " " + StrFor(128+(100)) + StrFor(128+(46)) + StrFor(128+(45)) + StrFor(128+(36)) + " " + StrFor(128+(16)) + StrFor(128+(20)); m_sroot = m_proot.appendChild(m_objXML.m_doc.createElement("rev:Service")); m_root = m_sroot.appendChild(m_objXML.m_doc.createElement("rev:Mnemonic")); m_root.text = "SNILS_VALIDATION"; m_root = m_sroot.appendChild(m_objXML.m_doc.createElement("rev:Version")); m_root.text = "1.00"; m_root = m_proot.appendChild(m_objXML.m_doc.createElement("rev:TypeCode")); StrOut = ("GSRV");//GSRV - взаимодействие в рамках оказания госуслуг. m_root.text = StrOut; m_root = m_proot.appendChild(m_objXML.m_doc.createElement("rev:Status")); StrOut = ("REQUEST"); m_root.text = StrOut; m_root = m_proot.appendChild(m_objXML.m_doc.createElement("rev:Date")); StrOut = (m_timestamp); m_root.text = StrOut; m_root = m_proot.appendChild(m_objXML.m_doc.createElement("rev:ExchangeType")); m_root.text = "2"; m_root = m_proot.appendChild(m_objXML.m_doc.createElement("rev:TestMsg")); StrOut = (""); m_root.text = StrOut; /*<rev:MessageData>*/ m_root = m_mes.appendChild(m_objXML.m_doc.createElement("rev:MessageData")); m_root = m_root.appendChild(m_objXML.m_doc.createElement("rev:AppData")); m_root = m_root.appendChild(m_objXML.m_doc.createElement("rev:request")); m_proot = m_root.appendChild(m_objXML.m_doc.createElement("snil:fio")); m_post = m_proot.appendChild(m_objXML.m_doc.createElement("pfr:FirstName")); ToUTF8(StrUpr(СНИЛС_Имя), StrOut); m_post.text = StrOut; m_post = m_proot.appendChild(m_objXML.m_doc.createElement("pfr:LastName")); ToUTF8(StrUpr(СНИЛС_Фамилия), StrOut); m_post.text = StrOut; m_post = m_proot.appendChild(m_objXML.m_doc.createElement("pfr:Patronymic")); ToUTF8(StrUpr(СНИЛС_Отчество), StrOut); m_post.text = StrOut; m_post = m_root.appendChild(m_objXML.m_doc.createElement("snil:snils")); StrOut = (СНИЛС_СНИЛС); m_post.text = StrOut; m_proot = m_root.appendChild(m_objXML.m_doc.createElement("snil:gender")); StrOut = (СНИЛС_Пол); m_proot.text = StrOut; m_proot = m_root.appendChild(m_objXML.m_doc.createElement("snil:pfr_date")); StrOut = DateToDDMMYYYY(СНИЛС_ДРожд); m_proot.text = StrOut; //DEBUG ONLY !!! //var fn ="..\\txtfile\\smev_fns\\test_snils_do_podpisi.xml"; //m_objXML.m_doc.save(fn); end; macro CreateMessage():integer end; macro ConvertDir(dir:string) var j:integer = 1, ind:integer = 1; while ( (j < strlen(dir)) ) if ((substr( dir, j, 1) != ".") and (substr( dir, j, 1) != "\\") and (substr( dir, j, 1) != "$")) break; end; j = j + 1; end; dir = substr( dir, j ); return dir; end; macro getFileNameCreator(type /* ==V_UNDEF*/):SMEVFileName if ( ValType( m_file_name_creator ) == V_UNDEF ) m_file_name_creator = SMEVFileName(type, m_date_form, getServfilePath(m_dir_out_setting)); end; return m_file_name_creator; end; macro GetFileName(type : string) : integer getFileNameCreator(type); return 0; OnError(er) return 1; end; macro CopyFileFromTempPath() macro copyFileExt(from, to) var ret:Bool = false; if(not isStandalone()) to = "$" + to; end; ret = CopyFile(from, to); return ret; end; private var ret:Bool = copyFileExt(getFileNameCreator().getTempFilePath() , getFileNameCreator().getFullFilePath()); return ret; end; macro CheckByXSD() var errstr:String; if( not m_xsd.validate(m_objXML.m_doc.xml, errstr)) CreateErrorXSD(errstr); return false; end; return true; end; macro Send() m_objCon.Send( Trim(Address), m_objXML.m_doc.xml, getFileNameCreator()); end; macro SaveXMLDoc():bool //Какие-то телодвижения по сохранению документа. var sreg = p_REGVAL_2; p_REGVAL_2 = true; p_noSaveArh = true; m_objXML.save( getFileNameCreator().getTempFilePath(), "UTF-8"); p_noSaveArh = false; p_REGVAL_2 = sreg; return true; OnError( er ) m_notif = m_notif + er.Message + "\n"; return false; end; macro SignIfNeedAndCheck() var ret = true; if(GetDSMode()) //Все нижеследующее имеет смысл лишь при включенной и настроенной криптографии if(ValType(crypto_api) == V_UNDEF) crypto_api = CRslCryptoApi(); //Инициализация cryptoApi end; if ( ExistFile(getFileNameCreator().getTempFilePath()) ) //Если есть что подписывать m_objXML = null; //Освобождаем объект. crypto_api.PutFileSign( CRYPD_SMEV_MESSAGES, getFileNameCreator().getTempFilePath(), getFileNameCreator().getTempSignedFilePath()); CopyFile(getFileNameCreator().getTempSignedFilePath(), getFileNameCreator().getTempFilePath()); RemoveFile(getFileNameCreator().getTempSignedFilePath()); m_objXML = TXML(not IsStandAlone(), "UTF-8"); //загружаем подписанный файл m_objXML.load(getFileNameCreator().getTempFilePath()); else RunError("ЭЦП:Нет файла для подписания:"+getFileNameCreator().getTempFilePath()); end; ret = CheckByXSD(); //Проверим подписанный файлик. end; return ret; OnError( er ) m_notif = m_notif + er.Message + "\n"; return false; end; end; class (TCreateMessage) TCreateSmevMsg( smparm ) macro CreateBodyMessage():integer var m_post; var StrOut:string = ""; CreateSMEV(); return 0; end; macro CreateMessage():integer var stat:integer = 0; if ( not CreateBodyMessage() ) m_root = m_objXML.m_doc.documentElement; m_proot = m_root.getElementsByTagName("soapenv:Header").item(0); if ( GetFileName( "02") ) return 1; end; //Сохраняем сформированный файл. if( not SaveXMLDoc()) return 1; //Не получилось сохранить end; //Подписываем при необходимости. if(not SignIfNeedAndCheck()) return 1; //Не получилось подписать end; if ( not stat ) CopyFileFromTempPath(); //Копируем файл из временного каталога в каталог из насторойки, только если ранее не было ошибок (При подписании, проверке по xsd, итп) if ( OnlineMode ) Send(); end; end; else stat = 1; end; return stat; end; macro ReadSMEVResponse() var response_fn, request_fn = getFileNameCreator().getFullFilePath(); var dom = activeX("MSXML2.DOMDocument"); var root, node0, node1, node2, node3, blocks, i, tag, val; response_fn = "..\\workfile\\response" + substr(request_fn, LastIndex(request_fn, "\\") + 1); response_fn = strsubst(response_fn, ".xml", "." + UserNumber()); while (not ExistFile(response_fn)) message("Ждём файл ответа..."); end; dom.Load(response_fn); blocks = dom.getElementsByTagName("Status"); i = 0; while (i < blocks.length) tag = blocks.item(i); val = tag.childnodes(0).text; i = i + 1; end; if (val == "INVALID") blocks = dom.getElementsByTagName("ns3:message"); i = 0; while (i < blocks.length) tag = blocks.item(i); val = tag.childnodes(0).text; i = i + 1; end; msgbox("Ошибка при проверке СНИЛС:|" + val); elif (val == "RESULT") blocks = dom.getElementsByTagName("ns4:result"); i = 0; while (i < blocks.length) tag = blocks.item(i); val = tag.childnodes(0).text; i = i + 1; end; if (val == "true") msgbox("Валидация успешна!|СНИЛС соответствует данной фамильно-именной группе"); else msgbox("Валидация НЕ УСПЕШНА!|СНИЛС НЕ соответствует данной фамильно-именной группе"); end; else msgbox("Неизвестный статус в ответе: " + val); end; end; initTCreateMessage(smparm.Dir, smparm.DateForm, smparm.TimeForm, smparm.Recipient, smparm.Recipient_name); end; macro CreateAndSendSMEVMessage() : bool var l_rec = TRecHandler("smevparm.tmp", "rs_temp.def"); var res : bool = true; l_rec.rec.Dir = "..\\txtfile\\smev_fns\\"; l_rec.rec.DateForm = date; l_rec.rec.TimeForm = time; l_rec.rec.Recipient = "SID0003822"; l_rec.rec.Recipient_name = "snils-validation"; var obj = TCreateSmevMsg(l_rec.rec); var stat = obj.CreateMessage(); if(0 != stat) res = false; else obj.ReadSMEVResponse(); end; return res; end; // ═════════════════════════════ Диалог ═════════════════════════════════════════════════════ Macro CheckFields(dlg) if (dlg.rec.Фамилия == "") msgbox("Задайте фамилию!"); SetFocus(dlg, FldIndex(dlg, "Фамилия")); return false; end; if (dlg.rec.Имя == "") msgbox("Задайте имя!"); SetFocus(dlg, FldIndex(dlg, "Имя")); return false; end; if (dlg.rec.Отчество == "") msgbox("Задайте отчество!"); SetFocus(dlg, FldIndex(dlg, "Отчество")); return false; end; /* if ((dlg.rec.Пол != "M") and (dlg.rec.Пол != "F")) msgbox("Задайте пол!"); SetFocus(dlg, FldIndex(dlg, "Пол")); return false; end; */ if ((dlg.rec.СНИЛС == "") or (StrLen(dlg.rec.СНИЛС) != 14)) msgbox("Задайте СНИЛС в правильном ФОРМАТЕ!"); SetFocus(dlg, FldIndex(dlg, "СНИЛС")); return false; end; return true; end; Macro SaveFields(dlg) СНИЛС_Фамилия = dlg.rec.Фамилия; СНИЛС_Имя = dlg.rec.Имя; СНИЛС_Отчество = dlg.rec.Отчество; СНИЛС_Пол = dlg.rec.Пол; СНИЛС_ДРожд = dlg.rec.ДРожд; СНИЛС_СНИЛС = dlg.rec.СНИЛС; End; Macro DlgProc(dlg, cmd, id, key) array mn; var stat = CM_DEFAULT; if (cmd == DLG_INIT) //InitFields(dlg); UpdateFields(dlg); stat = CM_IGNORE; elif (cmd == DLG_REMFOCUS) if (fldname(dlg, id) == "СНИЛС") // dlg.rec. = ...; ничего UpdateFields(dlg); end; elif (cmd == DLG_KEY) if (key == K_F2) if (CheckFields(dlg)) SaveFields(dlg); if (CreateAndSendSMEVMessage()) stat = CM_SAVE; else msgbox("Ошибка при формировании и отправке запроса в СМЭВ!|Обратитесь в ИТ отдел!"); end; else stat = CM_IGNORE; end; elif (key == K_F3) if (fldname(dlg, id) == "Пол") mn(0) = "M"; mn(1) = "F"; stat = menu(mn, "Пол", "Пол", 30, 10); if (stat >= 0) dlg.rec.Пол = mn(stat); end; stat = CM_IGNORE; end; elif (key == K_ENTER) if (fldname(dlg, id) == "ДРожд") SetFocus(dlg, FldIndex(dlg, "Фамилия")); stat = CM_IGNORE; end; elif (key == K_ESC) stat = CM_CANCEL; end; UpdateFields(dlg); end; return stat; End; // ══════════════════════════════════════════════════════════════════════════════════════════ Macro mkSNILSlbr(lbr) Var rc = lbr.AddPanel( "SNILS", 2, 2, 70, 15, lbr.EColour.SHLP, lbr.EFRame.UNARY ), elem; rc.Title = "Валидация СНИЛС через СМЭВ (сервис ПФР)"; rc.StatusLine = " F3 - выбор, F2 - Проверка, Esc - выход "; elem = rc.AddLabel( 5, 2, "Фамилия:" ); elem = rc.AddField( 28, 2, lbr.EFieldType.EDIT, lbr.EFocus.YES, lbr.EDataType.V_STRING, "Фамилия", 30, 1 ); elem = rc.AddLabel( 5, 4, "Имя:" ); elem = rc.AddField( 28, 4, lbr.EFieldType.EDIT, lbr.EFocus.YES, lbr.EDataType.V_STRING, "Имя", 30, 1 ); elem = rc.AddLabel( 5, 6, "Отчество:" ); elem = rc.AddField( 28, 6, lbr.EFieldType.EDIT, lbr.EFocus.YES, lbr.EDataType.V_STRING, "Отчество", 30, 1 ); elem = rc.AddLabel( 5, 8, "СНИЛС (123-456-789 12) :" ); elem = rc.AddField( 28, 8, lbr.EFieldType.EDIT, lbr.EFocus.YES, lbr.EDataType.V_STRING, "СНИЛС", 14, 1); elem = rc.AddLabel( 5, 10, "Пол:" ); elem = rc.AddField( 28, 10, lbr.EFieldType.NOEDIT, lbr.EFocus.YES, lbr.EDataType.V_STRING, "Пол", 1, 1); elem = rc.AddLabel( 5, 12, "Дата рождения:" ); elem = rc.AddField( 28, 12, lbr.EFieldType.EDIT, lbr.EFocus.YES, lbr.EDataType.V_DATE, "ДРожд", 10); elem = rc.AddLabel( 16, 16, "F3 - выбор, F2 - Проверить, Esc - выход" ); End; // ══════════════════════════════════════════════════════════════════════════════════════════ Macro MkLbrFile Var LbrName = "..\\mac\\userb\\snils.lbr", lbr = TLbrFile( LbrName, "C" ); mkSNILSlbr( lbr ); lbr.Save(); //сохраняем ресурсы в файле lbr = NULL; return LbrName; End; // ══════════════════════════════════════════════════════════════════════════════════════════ // ВХОД В ПРОГРАММУ // ══════════════════════════════════════════════════════════════════════════════════════════ Var LbrName = MkLbrFile(); Var test = TRecHandler( "snils", LbrName, TRUE ); // ═════════════════════════════ Диалог ═════════════════════════════════════════════════════ if (not RunDialog(test, "DlgProc")) exit(1); end; exit(1); // ═════════════════════════════ Диалог ═════════════════════════════════════════════════════