Проверка безопасности пользователей 1С

Со временем, даже в небольших конфигурациях 1С количество пользователей чаще всего увеличивается. А если еще и компания достаточно большая, то возникает необходимость следить за тем, чтобы учётки вовремя отключались. А еще и были безопасны с точки зрения использования. Например: достаточно часто пользователь меняет пароль, включена ли у него доменная авторизация и т.п., Фактически полноценная проверка безопасности пользователей 1С

В моём случае возникла необходимость регулярно мониторить служебные учётные данные. Количество разработчиков большое. Количество http и web сервисов не большое, но постоянно растёт, т.к. мы придерживаюсь принципа: один сервис — одна учётка для доступа. Делается это для того чтобы было удобнее логировать и отслеживать кто что и как. Соответственно необходимо чтобы эти служебные пользователи имели строго определенные доступы, и не имели возможность непосредственного входа в 1С через толстый и тонкий клиенты.

После калькуляции требований безопасности я выявил следующие показатели для того чтобы считать учётную запись «неблагонадёжной»:

  • нет доменной авторизации
  • разрешен вход в 1с (галочка «Доступ к информационной базе разрешен» в справочнике Пользователи)
  • у пользователя включены роли ЗапускВебКлиента, ЗапускТолстогоКлиента, ЗапускВнешнегоСоединения
  • При ответе «Да» на все три условия, пользователя помещаю в соответствующий список.
  • Кроме того дополнительно провожу проверку, что в правах одной из ролей есть права: ЗапускВебКлиента, ЗапускТолстогоКлиента, ЗапускВнешнегоСоединения

В итоге родил такую обработку:

Процедура СК_ГР_ПроверкаБезопасностиПользователя() экспорт
	УстановитьПривилегированныйРежим(Истина);
	Выборка = ПользователиИнформационнойБазы.ПолучитьПользователей(); 
	МассивДляОтчета=Новый Массив();
	данные="";   
	бд=НСтр(СтрокаСоединенияИнформационнойБазы(), "Ref"); 
	Для Каждого ЭлементМассива Из Выборка Цикл 
		если ЭлементМассива.АутентификацияОС=ложь тогда
			если ЭлементМассива.АутентификацияСтандартная=истина тогда				
				инф=Новый Структура("полноеимя,имя,email,датапароля,показыватьвспискевыбора,роли,пользователь,ЗапускВебКлиента,ЗапускТолстогоКлиента,ЗапускТонкогоКлиента,ЗапускВнешнегоСоединения");				
				инф.полноеимя=ЭлементМассива.ПолноеИмя;
				инф.имя=ЭлементМассива.Имя;
				инф.email=ЭлементМассива.АдресЭлектроннойПочты;
				инф.датапароля=ЭлементМассива.ДатаУстановкиПароля;
				инф.показыватьвспискевыбора=ЭлементМассива.ПоказыватьВСпискеВыбора;
				инф.роли="";
				
				ЕстьПароль = ЭлементМассива.ПарольУстановлен; 
				Роли = ЭлементМассива.Роли; 		
				Для Каждого Роль Из Роли Цикл 					
					если ПравоДоступа("ВебКлиент",Метаданные,Роль) тогда
						инф.роли=инф.роли+Роль.Имя+", ";
					иначеесли ПравоДоступа("ВнешнееСоединение",Метаданные,Роль) тогда
						инф.роли=инф.роли+Роль.Имя+", ";
					иначеесли ПравоДоступа("ТолстыйКлиент",Метаданные,Роль) тогда
						инф.роли=инф.роли+Роль.Имя+", ";
					иначеесли ПравоДоступа("ТонкийКлиент",Метаданные,Роль) тогда
						инф.роли=инф.роли+Роль.Имя+", ";
					конецесли;						
				КонецЦикла; 				
				поль=Справочники.Пользователи.НайтиПоРеквизиту("ИдентификаторПользователяИБ",ЭлементМассива.УникальныйИдентификатор);
				    ЗапускРоль="";
					если поль<>Справочники.Пользователи.ПустаяСсылка() тогда
						инф.ЗапускВебКлиента=УправлениеДоступом.ЕстьРоль("ЗапускВебКлиента",, поль);					
						если инф.ЗапускВебКлиента=истина тогда
							ЗапускРоль=ЗапускРоль+"Веб, ";	
						конецесли;
						инф.ЗапускТолстогоКлиента=УправлениеДоступом.ЕстьРоль("ЗапускТолстогоКлиента",, поль);
						если инф.ЗапускТолстогоКлиента=истина тогда
							ЗапускРоль=ЗапускРоль+"Толстый, ";	
						конецесли;						
						инф.ЗапускТонкогоКлиента=УправлениеДоступом.ЕстьРоль("ЗапускТонкогоКлиента",, поль);
						если инф.ЗапускТонкогоКлиента=истина тогда
							ЗапускРоль=ЗапускРоль+"Тонкий, ";	
						конецесли;						
						инф.ЗапускВнешнегоСоединения=УправлениеДоступом.ЕстьРоль("ЗапускВнешнегоСоединения",, поль);
						если инф.ЗапускВнешнегоСоединения=истина тогда
							ЗапускРоль=ЗапускРоль+"Внешние, ";	
						конецесли;
						
					конецесли;				
								
				инф.пользователь=поль.Наименование;				
				МассивДляОтчета.Добавить(инф);
				
				данные=данные+"<tr>";
				данные=данные+" <td>"+инф.полноеимя+"</td>";
				данные=данные+" <td>"+инф.имя+"</td>";
				данные=данные+" <td>"+инф.пользователь+"</td>";
				данные=данные+" <td>"+инф.email+"</td>";
				данные=данные+" <td>"+инф.датапароля+"</td>";
				данные=данные+" <td>"+инф.показыватьвспискевыбора+"</td>";				
				данные=данные+" <td>"+ЗапускРоль+"</td>";
				данные=данные+" <td>"+инф.роли+"</td>";
				данные=данные+"</tr>";
				
			Конецесли;
		Конецесли;
	КонецЦикла;
		
	если МассивДляОтчета.Количество()>0 тогда
		 			
		 	тело="<style>td {border: 1px solid;} th{border: 1px solid;} table.table {word-wrap:true;border-collapse: collapse;border-spacing: 0;}table.table > thead > tr > th {font-size: 14px;font-weight: normal;padding-top: 7px;padding-bottom: 7px;}.table > thead > tr > th {vertical-align: bottom;border-bottom: 2px solid #ddd;}table.table th {background-color: #153e76;}</style>";						
			тело=тело+"Критерии попадания в этот список: отключена доменная авторизация, разрешен вход в 1С<br/>";			
		 	тело=тело+"<strong>Подозрительные учётки</strong>: <br/>";
    		тело=тело+"<table class='table'>";
    		тело=тело+"  <thead>";
    		тело=тело+"    <tr>";
    		тело=тело+"     <th scope='col'> Полное имя</th>";
			тело=тело+"     <th scope='col'> Имя</th>";
			тело=тело+"     <th scope='col'> Пользователь</th>";			
			тело=тело+"     <th scope='col'> Email</th>";
			тело=тело+"     <th scope='col'> Дата пароля</th>";
			тело=тело+"     <th scope='col'> В списке выбора</th>";
			тело=тело+"     <th scope='col'> Вид запуска</th>";
			тело=тело+"     <th scope='col'> Роли с доступом в 1С</th>";
    		тело=тело+"   </tr>";
    		тело=тело+" </thead>";
    		тело=тело+" <tbody>";    		 
		 	тело=тело+данные;		 
		 	тело=тело+"  </tbody>";
    		тело=тело+"</table>";

						
		 emails=Новый Массив();	
		 emails.Добавить("цкуаука@куауцкацук.ru");
		 
		 для каждого email из emails цикл
			 если email<>"" тогда
				 попытка
	 			 		ПараметрыПисьма = Новый Структура("Кому, Тема, Тело,ТипТекста", email, "Подозрительные учётки в БД: "+бд, тело,"HTML");
						если бд="укму" тогда
						 УчетнаяЗаписьПочты = РаботаСПочтовымиСообщениями.ПолучитьСистемнуюУчетнуюЗапись();						
				 		 РаботаСПочтовымиСообщениями.ОтправитьСообщение(УчетнаяЗаписьПочты, ПараметрыПисьма);
					    иначеесли бд="куепуке" тогда
						 УчетнаяЗаписьПочты = РаботаСПочтовымиСообщениями.ПолучитьСистемнуюУчетнуюЗапись();
						 РаботаСПочтовымиСообщениями.ОтправитьСообщение(УчетнаяЗаписьПочты, ПараметрыПисьма);
					    иначеесли бд="укепуке" тогда					 
						 РаботаСПочтовымиСообщениями.ОтправитьПочтовоеСообщение(РаботаСПочтовымиСообщениями.СистемнаяУчетнаяЗапись(),ПараметрыПисьма);					 					 
					    иначеесли бд="куепук" тогда					 
						 РаботаСПочтовымиСообщениями.ОтправитьПочтовоеСообщение(РаботаСПочтовымиСообщениями.СистемнаяУчетнаяЗапись(),ПараметрыПисьма);					 
					    конецесли;						 
					исключение
						ЗаписьЖурналаРегистрации("Ошибка", УровеньЖурналаРегистрации.Ошибка,,ОписаниеОшибки(),);			
				 конецпопытки;
	 		 конецесли;									 
	     конеццикла;		 		 
	конецесли;
	  УстановитьПривилегированныйРежим(ложь);
КонецПроцедуры

Обработкой я перебираю всех пользователей информационной базы, и ищу соответствующего пользователя из справочника «Пользователи». В том случае, если пользователя признаю потенциально не безопасным, то отправляю заинтересованному лицу уведомление на электронную почту.

проверка безопасности пользователей 1С

Почитайте еще по теме 1С тут

Файл docx на основе шаблона при помощи PHP

Довольно часто встречается задача автоматизировать заполнение всяческих заявлений..ну например в бухгалтерию. Это вполне можно сделать и на PHP, позволив пользователю на форме веб страницы заполнить основные данные, а затем отдав ему уже сформированный на основе шаблона файл формата docx (файл docx на основе шаблона).

HTML часть может выглядеть примерно так:

<div class="rendered-form">
    <div class="formbuilder-text form-group field-position_at_work">
        <label for="position_at_work" class="formbuilder-text-label">Ваша должность
            <br>
        </label>
        <input type="text" placeholder="Наиглавнейший церемонимейстер" class="form-control" name="position_at_work" access="false" id="position_at_work">
    </div>
    <div class="formbuilder-text form-group field-me_unit">
        <label for="me_unit" class="formbuilder-text-label">Подразделение</label>
        <input type="text" placeholder="Отдел развития и автоматизации" class="form-control" name="me_unit" access="false" id="me_unit">
    </div>
    <div class="formbuilder-text form-group field-me_name">
        <label for="me_name" class="formbuilder-text-label">Ваше ФИО
            <br>
        </label>
        <input type="text" placeholder="Иванов Иван Иванович" class="form-control" name="me_name" access="false" id="me_name">
    </div>
    <div class="formbuilder-date form-group field-date_start">
        <label for="date_start" class="formbuilder-date-label">Дата начала отпуска
            <br>
        </label>
        <input type="date" class="form-control" name="date_start" access="false" id="date_start">
    </div>
    <div class="formbuilder-number form-group field-long_vacation">
        <label for="long_vacation" class="formbuilder-number-label">Продолжительность отпуска
            <br>
        </label>
        <input type="number" class="form-control" name="long_vacation" access="false" value="14" min="1" max="31" id="long_vacation">
    </div>
    <div class="formbuilder-button form-group field-button-1714717346219">
        <button onclick="CreateZay()" type="button" class="btn-success btn" name="button-1714717346219" access="false" style="success" id="button-1714717346219">Сформировать заявление
            <br>
        </button>
    </div>
</div>

На странице увидим что-то вроде:

файл docx на основе шаблона

На JavaScript создам функцию — обработчик нажатия на кнопку «Сформировать заявление». Функция делает запрос на сервер, а в ответ получает сформированный файл. Браузер автоматически предложит его сохранить.

function CreateZay(){
  console.log("--создаётся заявление..");  
  
        var xhr = new XMLHttpRequest();
        xhr.open('POST', '/sever/zayav.php', true);
        
        xhr.responseType = 'blob';     
        xhr.onload = function(e) {
            if (this.status == 200) {
                var link=document.createElement('a');
                link.href=window.URL.createObjectURL(this.response);                
                link.download="result.docx";
                link.click();
            }
            else {
                console.log(e);
            }
        };     
        var form_data = new FormData();        
        form_data.append("position_at_work", position_at_work.value);
        form_data.append("me_unit", me_unit.value);
        form_data.append("me_name", me_name.value);
        form_data.append("date_start", date_start.value);
        form_data.append("long_vacation", long_vacation.value);
        xhr.send(form_data);                 
};  

С клиентской частью (ну которая в браузере) разобрались. Теперь займемся сервером. Чтобы ничего не изобретать, воспользуемся пакетом phpoffice/phpword:

composer require phpoffice/phpword

Далее подготовим файл-шаблон. Можно в любом редакторе, который поддерживает расширение docx. В файле , те части которые мы хотим заменить, обрамляем ${имя_переменноя}, чтобы получилось например что-то вроде:

Далее, серверная часть, которая заполняет непосредственно сам шаблон:

<?php
$dt_start=strtotime($_POST["date_start"]);
$dt_end=strtotime($_POST["date_start"]." ".$_POST["long_vacation"]." day");

$newformat_start = date('d.m.Y',$dt_start);
$newformat_end = date('d.m.Y',$dt_end);

//var_dump($_POST);
//die();

require $_SERVER["DOCUMENT_ROOT"].'/sever/phpword/autoload.php';
//создаем класс
$phpWord = new  \PhpOffice\PhpWord\PhpWord(); 
$_doc = new \PhpOffice\PhpWord\TemplateProcessor('templates/template_1.docx');


$_doc->setValue('position_at_work', $_POST["position_at_work"]); 
$_doc->setValue('me_unit', $_POST["me_unit"]); 
$_doc->setValue('me_name', $_POST["me_name"]); 
$_doc->setValue('long_vacation', $_POST["long_vacation"]); 
$_doc->setValue('date_start', $newformat_start); 
$_doc->setValue('date_end', $newformat_end); 

$res=$_doc->saveAs($_SERVER["DOCUMENT_ROOT"]."/sever/tmp.docx");

$fil=file_get_contents($_SERVER["DOCUMENT_ROOT"]."/sever/tmp.docx");
echo $fil;

В результате мы получили файл docx. Другие статьи по PHP можете почитать здесь

Текущая дата в input

Задача: Необходимо чтобы при отображении на HTML странице поля input с типом дата, автоматически подставлялась определенная дата (заполнение текущей датой поля input). Ну например текущая+14 дней.

Решение: собственно без javascript тут не обойтись (ну если исключить вариант, что html генерируется на сервере, и соответственно заполняется поле value. Но это не наш метод (с)

HTML:

    <div class="formbuilder-date form-group field-date_start">
        <label for="date_start" class="formbuilder-date-label">Дата начала отпуска
            <br>
        </label>
        <input type="date" class="form-control" name="date_start" access="false" id="date_start">
    </div>

JavaScript:

<script>
    var date = new Date(Date.now());
    date.setDate(date.getDate() + 14);    
    date_start.value=date.toISOString().split("T")[0];
</script>    

Что тут интересного? Ну фактически мы пользуемся тем, что value у тега input с типом даты обязательно должно быть в формате гггг-мм-дд, т.е. ISO формат, а в ISO формат мы можем пере конвертировать дату полученную при помощи функции Date. Время нам не нужно, поэтому отсекаем его, разделив дату по разделителю «Т», и взяв первый элемент массива.

заполнение текущей датой поля input

До чего дошел прогресс (с)

Хм..однако. Попробовал новую нейросеть для сочинения музыки и накладывания слов на мотив музыки. И был удивлён. Прогресс очевиден, и музыка и песни получающиеся действительно пригодны для прослушивания.

Вот пример того что получилось:

Попробовать самому можно здесь.

нейросеть для сочинения музыки

SSL certificate problem при клонировании git

При клонировании при помощи git репозитария, возникла ошибка «SSL certificate problem». Обычно это означает что корневой сертификат не является доверенным. В моём случае, всё хорошо, просто тов. Касперский лезет туда куда не нужно бы лезть — а именно для того чтобы перехватывать трафик пропускает весь трафик на порту 433 через себя, подсовывая свой корневой сертификат. Отключить сиё в виду определенных причин я не могу, потоэтому придётся научить git игнорировать ошибки проверки сертификата. Сделать это можно двумя способами: длинным и коротким:

git config --global http.sslVerify false

Ну а далее, как обычно:

git clone https://git.xn--укацукацук.xn--p1ai/donpadlo/3dmodels.git

Git чуть ругнётся, но клон сделает:

SSL certificate problem

Еще кое-что о git можно почитать тут

1 25 26 27 28 29 310