Top.Mail.Ru
Центр помощи / Для администратора / 4. Интеграции / Синхронизация пользователей / Синхронизация пользователей по ODBC: как устроена

Синхронизация пользователей по ODBC: как устроена

Приложение UnSpot ODBC SCIM Adapter переносит в UnSpot данные сотрудников из вашей базы: карточки пользователей, оргструктуру и статусы в расписании. Эта статья описывает устройство обмена — кто его инициирует, какие данные и по какому протоколу уходят из вашего контура, что при этом не передаётся, где приложение хранит токены и что попадает в его журнал. Она адресована службе информационной безопасности, которая согласовывает использование интеграции. Пошаговая установка, подготовка данных и настройка описаны в статье «Настройка синхронизации по ODBC (UnSpot ODBC SCIM Adapter)».

Как работает приложение

Приложение состоит из двух частей в одном исполняемом файле: окна настройки и службы Windows UnSpotOdbcScimService, которая и выполняет синхронизацию. Администратор один раз задаёт параметры в окне настройки и запускает службу — дальше она работает в фоне без участия пользователя: раз в заданный интервал (от 1 до 24 часов) подключается к вашей базе данных через ODBC, забирает подготовленные данные и передаёт их в UnSpot по HTTPS. Первый цикл начинается сразу после запуска службы.

За один цикл служба последовательно синхронизирует до трёх наборов данных:

  • Пользователи (всегда) — карточки сотрудников: создание, обновление и блокировка по протоколу SCIM 2.0.
  • Оргструктура (если включена) — дерево подразделений компании с руководителями, тоже по SCIM.
  • Статусы расписания (если включены) — отметки «удалённая работа», «отпуск», «больничный» и другие нерабочие статусы в расписании сотрудников, через External API UnSpot.

Источником данных служат три представления (view) или таблицы с фиксированными именами и колонками, которые вы создаёте в своей базе поверх реальных данных: users_for_unspot, org_structure_for_unspot и user_schedule_for_unspot. Благодаря этому приложению не важно, как устроена ваша схема данных: любую структуру можно привести к требуемому виду обычным SQL-представлением. Состав колонок и примеры представлений — в статье «Настройка синхронизации по ODBC».

Описанное ниже поведение соответствует версии приложения 1.3.0.

Направление и инициатор обмена

Инициатор обмена всегда один — служба на вашей машине. UnSpot к вашему контуру не обращается: вебхуков, обратных вызовов и подписок на события в этой интеграции нет, и служба не открывает входящих портов — сетевых слушателей в ней не заведено.

СоединениеКто инициируетЧто происходитКогда
Приложение → ваша база (ODBC)приложениеЧтение подготовленных представлений. В базу приложение ничего не пишет: за весь цикл выполняются только запросы SELECTкаждый цикл
Приложение → UnSpot (SCIM 2.0)приложениеЧтение текущего списка пользователей UnSpot, затем создание, обновление и удаление карточек; при включённой оргструктуре — замена дерева подразделенийкаждый цикл
Приложение → UnSpot (External API)приложениеПередача дневных статусов расписания, по одному запросу на статускаждый цикл, если включены «Статусы расписания»
UnSpot → ваш контурВходящих подключений нет

Обратный поток данных в интеграции есть, но только в одну сторону — в оперативную память приложения. Перед сверкой служба постранично забирает из UnSpot текущий список пользователей: идентификатор, externalId, логин (email), имя и фамилию, должность, телефон, подразделение, руководителя, номер пропуска, табельный номер и признак активности. Эти данные нужны, чтобы понять, что изменилось; на диск они не сохраняются и в вашу базу не записываются — цикл заканчивается, список исчезает вместе с ним.

Жёстко заданных адресов в приложении нет: единственные исходящие соединения — те, что вы указали в настройках (источник данных ODBC, адрес SCIM и адрес External API). Телеметрии, обращений к серверам разработчика и автообновления в приложении нет.

Как работает синхронизация

Пользователи

Каждый цикл — это полная сверка: приложение забирает из UnSpot текущий список пользователей по SCIM и сравнивает его со строками представления users_for_unspot. Сопоставление идёт в два прохода: сначала по идентификатору (колонка id ↔ поле externalId в UnSpot), затем оставшиеся — по email без учёта регистра. По результатам сверки:

  • Новые сотрудники (есть в базе, нет в UnSpot) — создаются. Email становится логином, значение id записывается в externalId.
  • Изменившиеся — обновляются. Сравниваются только те поля, которые отмечены в настройках приложения: имя, фамилия, email и включённые дополнительные поля (отдел, руководитель, должность, телефон, номер пропуска, табельный номер).
  • Исчезнувшие из выборки (уволенные или отфильтрованные) — удаляются из UnSpot: карточка сотрудника архивируется, пропадает из списков и теряет доступ. Активные брони снимаются, но данные и история остаются в системе.
  • Вернувшиеся в выборку — если удалённый ранее сотрудник снова появился в данных, его учётная запись восстанавливается из архива по email автоматически. Настройки доступа задаются заново (группы по умолчанию, новый пароль), а если включены приветственные письма — сотрудник получит новое приглашение.

Пользователи, заведённые в UnSpot вручную (не через синхронизацию), приложение не трогает и не удаляет. Если email такого пользователя совпал с email сотрудника из базы, карточка «подхватывается» синхронизацией: в неё записывается externalId, и дальше она обновляется из базы как обычно.

Руководитель указывается в данных как email. Если на момент создания сотрудника его руководителя ещё нет в UnSpot, приложение сначала создаст всех сотрудников, а затем вторым проходом проставит руководителей — поэтому иерархия любой глубины корректно загружается за один цикл, порядок строк в выборке не важен.

Ошибка на одном сотруднике не останавливает цикл: она записывается в журнал, и приложение переходит к следующей записи. А вот ошибка чтения из базы (например, NULL в обязательной колонке или отсутствующая колонка) прерывает синхронизацию пользователей целиком: в этом цикле в UnSpot не уйдёт ни одной карточки. На оргструктуру и статусы расписания это не влияет — они читаются отдельными запросами и синхронизируются независимо.

Оргструктура

Если в настройках отмечена «Оргструктура», после пользователей приложение отправляет в UnSpot дерево подразделений из представления org_structure_for_unspot. Синхронизация односторонняя и полная: переданный список целиком заменяет оргструктуру в UnSpot одним запросом. Каждая строка — это путь подразделения от корня с разделителем «/» (например, Компания/Департамент продаж/Отдел B2B), при необходимости — с описанием и email руководителя подразделения.

Статусы расписания

Если отмечены «Статусы расписания», приложение дополнительно передаёт в UnSpot дневные статусы сотрудников из представления user_schedule_for_unspot: удалённая работа, отпуск, больничный, командировка и любые другие нерабочие отметки, а также сброс статуса (возврат к обычному рабочему дню). Статусы отображаются в расписании сотрудника и видны коллегам. Этот поток идёт не по SCIM, а через External API UnSpot (метод обновления статуса в расписании) и требует отдельного токена — см. справочник «External API: обновление статуса в расписании».

Особенности этого потока:

  • Передаются только статусы с датой в окне ±45 дней от текущего дня.
  • Выборка инкрементальная: после первого успешного прогона приложение запоминает момент синхронизации и дальше берёт только строки, у которых updated_at не старше этой отметки. Отметка берётся по часам машины с приложением, а сравнение выполняет СУБД — следите, чтобы часы обеих машин были синхронизированы, иначе часть изменений может не попасть в выборку.
  • Статусы отправляются по одному с паузой в 1 секунду — так устроено ограничение частоты запросов External API (1 запрос в секунду).
  • Если UnSpot ответил кодом 401 (неверный или истёкший токен) или 429 (превышен лимит запросов), передача останавливается, отметка времени не сдвигается, и в следующем цикле приложение повторит незавершённую порцию.
  • Учитывайте: установка статуса на дату — как и его сброс — автоматически снимает собственные брони рабочих столов сотрудника на эту дату (будущая бронь удаляется, уже начавшаяся останавливается). Броней переговорных комнат и парковочных мест это не затрагивает.

Что передаётся

Из базы читаются только перечисленные ниже колонки трёх представлений — других запросов приложение не выполняет. Состав колонок в запросе зависит от галочек в окне настройки: невыбранные поля не читаются и не передаются.

Карточки сотрудников — представление users_for_unspot:

Колонка в базеЧто содержитКуда попадает в UnSpotКогда читается
idИдентификатор сотрудника в вашей системеexternalIdвсегда
emailРабочая почта — персональные данныеuserName (логин), приводится к нижнему региструвсегда
first_nameИмя — персональные данныеname.givenNameвсегда
last_nameФамилия — персональные данныеname.familyNameвсегда
departmentПодразделение сотрудника — персональные данныеdepartment в расширении enterpriseпри поле «Отдел»
managerEmail руководителя — персональные данныеmanager в расширении enterpriseпри поле «Руководитель»
positionДолжность — персональные данныеtitleпри поле «Должность»
phoneРабочий телефон — персональные данныеphoneNumbers с типом workпри поле «Телефон»
number_passНомер пропуска в СКУД — персональные данныеnumberPass в расширении UnSpotпри поле «Номер пропуска»
employee_idТабельный номер — персональные данныеemployeeId в расширении UnSpotпри поле «Табельный номер»

Итого из вашего контура уходят такие персональные данные сотрудников: фамилия, имя, рабочий email, а при включении соответствующих полей — рабочий телефон, должность, подразделение, email руководителя, табельный номер и номер пропуска в системе контроля доступа. Отчество, дата рождения, домашний адрес, личный телефон, паспортные данные, оклад, фотография и любые другие атрибуты сотрудника приложение из базы не запрашивает.

Дерево подразделений — представление org_structure_for_unspot. Все три колонки читаются всегда, когда включена «Оргструктура»:

Колонка в базеЧто содержитКуда попадает в UnSpot
pathПолный путь подразделения от корня с разделителем «/»path
descriptionОписание подразделенияdescription
managedByEmail руководителя подразделения — персональные данныеmanager

Дневные статусы — представление user_schedule_for_unspot. Читается и передаётся только при включённых «Статусах расписания»:

Колонка в базеЧто содержитКуда попадает в UnSpot
user_emailEmail сотрудника — персональные данныеuserEmail
dateДата статусаdate
status_typeТип статуса: REMOTE_WORK, NOT_WORKING или пусто (сброс)statusType
status_nameОтображаемое название статуса, например «Отпуск»statusName
status_codeКороткий код статуса, например «ОТ»statusCode
updated_atМомент последнего изменения строкине передаётся — колонка используется только в условии выборки

Причина отсутствия сотрудника или подразделения в выборке приложению не сообщается и в UnSpot не уходит: передаётся сам факт, что записи больше нет. Что делает UnSpot с исчезнувшей записью, описано выше, в разделе «Пользователи».

Что не передаётся

Отдельно перечислим то, чего в обмене нет:

  • Пароли сотрудников — ни в каком виде. Приложение не читает их из базы и не отправляет в UnSpot; пароль новому пользователю UnSpot назначает сам.
  • Фотографии и аватары — такого поля в обмене нет.
  • Любые колонки базы, кроме перечисленных выше — приложение формирует запрос из фиксированного списка колонок, «выбрать всё» оно не умеет.
  • Группы, роли и права доступа UnSpot — они назначаются в UnSpot и синхронизацией не управляются.
  • Брони, расписание, аналитика и другие данные UnSpot — обратно в вашу базу не возвращаются. Приложение выполняет к базе только запросы на чтение.
  • Учётные данные вашей СУБД — строка подключения ODBC используется только на вашей машине и в UnSpot не уходит.
  • Токены — в журнал приложения не записываются: они передаются заголовком авторизации, а в журнал попадает только тело запроса.

Протокол, порт и шифрование

СоединениеКудаПортАутентификация
SCIM 2.0адрес из поля «SCIM URL», обычно https://ваш-домен.unspot.ru/api/scim; приложение дописывает к нему /Users и /OrgUnits443заголовок Authorization, схема Bearer, токен SCIM
External APIадрес из поля «URL API UnSpot», обычно https://ваш-домен.unspot.ru/api/external/v1/user-schedule443заголовок Authorization, схема Bearer, токен «Импорт расписания сотрудника»
ODBCсервер вашей СУБД — адрес берётся из системного DSN или из строки подключенияпо вашей СУБДпо настройкам источника данных: логин и пароль СУБД либо Windows-аутентификация
Входящиенет
  • Адрес UnSpot используется ровно в том виде, в каком он сохранён в настройках: приложение не подставляет ни схему, ни порт и не проверяет, что адрес начинается с https://. Указывайте адрес со схемой HTTPS — иначе запросы уйдут в открытом виде.
  • Проверка сертификата — стандартная для Windows: приложение работает через штатный HTTPS-клиент .NET с настройками по умолчанию. Обработчика, который отключал бы проверку сертификата, в приложении нет, и в настройках такой возможности тоже нет. Самоподписанный сертификат приведёт к ошибке подключения.
  • Версия TLS и набор шифров согласуются средствами Windows на этой машине — в приложении они не фиксируются.
  • Тело запросов — JSON: тип application/scim+json для SCIM и application/json для статусов расписания.
  • Канал до СУБД шифруется настройками ODBC-драйвера и источника данных (для Microsoft SQL Server это, например, параметры Encrypt и TrustServerCertificate). Приложение в эти параметры не вмешивается и своих значений не подставляет — задайте их сами при создании источника данных.

Где хранятся токены и учётные данные

Все параметры приложения лежат в одном файле config.json в каталоге приложения — по умолчанию C:\Program Files\Umbrella IT\UnSpotOdbcScim. Это обычный текстовый JSON. Реестр Windows, Windows Credential Manager и защиту DPAPI приложение не использует.

Что хранитсяГдеВ каком виде
Строка подключения ODBC — вместе с логином и паролем СУБД, если вы указали их прямо в нейconfig.jsonоткрытый текст
Токен SCIM 2.0config.jsonоткрытый текст
Токен External API для статусов расписанияconfig.jsonоткрытый текст
Адреса SCIM и External API, набор синхронизируемых полей, интервал, признак автозапускаconfig.jsonоткрытый текст
Логин и пароль СУБД, если они заданы в системном источнике данныхпараметры системного DSN, которые ведёт Windowsпо правилам ODBC-драйвера

Шифрования файла настроек в приложении нет — оба токена и строка подключения хранятся в открытом виде. Ограничьте доступ к каталогу приложения средствами операционной системы: при стандартных разрешениях каталога Program Files изменять файл может только администратор, а прочитать — любой локальный пользователь. В окне настройки токены тоже показываются открытым текстом: поля ввода не маскируются.

Служба регистрируется командой sc.exe create без указания учётной записи, поэтому Windows запускает её от NT AUTHORITY\SYSTEM — самой привилегированной локальной учётной записи. Именно ей нужно выдавать права в базе при Windows-аутентификации. Приложение регистрирует службу только если её ещё нет, поэтому учётную запись можно сменить штатными средствами Windows — приложение это не переопределит. Если вы её меняете, выдайте новой учётной записи право на чтение каталога приложения и на запись в подкаталог logs. Само окно настройки запускается с правами администратора: без них служба не регистрируется и не управляется.

Что хранится на машине с приложением

Приложение не использует собственную базу данных. Всё, что оно оставляет на диске, — три объекта в каталоге приложения:

Файл или каталогЧто внутриСрок жизниКак очистить
config.jsonПараметры приложения, включая оба токена и строку подключения ODBCдо удаления приложенияудалить приложение — файл стирается автоматически
user_schedule_updated_at.jsonОдна отметка времени: момент последней успешной синхронизации статусов расписания, в UTC. Персональных данных в файле нетдо удаления приложенияудалить файл при остановленной службе — следующий цикл возьмёт статусы за всё окно ±45 дней
logs\service-log.txt и архивыЖурнал работы службы: текущий файл и до 7 суточных архивовротация раз в сутки, хранятся 7 архивовудалить файлы; при удалении приложения каталог удаляется целиком

Выбранные из базы данные нигде не кэшируются: список сотрудников, дерево подразделений, статусы и ответ UnSpot существуют только в памяти процесса на время цикла и на диск не записываются.

Что попадает в журнал. На уровне Info, который включён по умолчанию, пишутся служебные сообщения цикла (сколько строк выбрано из базы, сколько пользователей создано, обновлено и удалено, ошибки подключения) и по каждому изменению — email и идентификатор сотрудника, например: «Создаём пользователя: i.petrov@company.ru (7f3a91c2-44b0)». То же при обновлении карточки, смене руководителя и удалении.

На уровне Debug журнал становится существенно подробнее — оцените это до того, как включать его:

  • тексты выполняемых SQL-запросов и значения их параметров;
  • тела всех запросов к UnSpot целиком — то есть карточки сотрудников с фамилией, именем, email, телефоном, должностью, подразделением, табельным номером и номером пропуска, а также передаваемые статусы расписания;
  • тела ответов UnSpot на создание, обновление и удаление;
  • какое именно поле изменилось у конкретного сотрудника.

Иными словами, Debug-журнал — это выгрузка персональных данных сотрудников в текстовый файл на диске. Токены в него не попадают, но всё остальное попадает. Включайте этот уровень только на время разбора проблемы и удаляйте файлы журнала после. Как переключить уровень и где лежит журнал — в статье «Настройка синхронизации по ODBC».

Требования к сети и правам

Что нужноГдеЗачем
Исходящий HTTPS, порт 443с машины приложения к домену вашей компании в UnSpotзапросы SCIM 2.0 и External API
Доступ к серверу СУБДс машины приложения, порт по вашей СУБДчтение трёх представлений
Входящие правилане нужныприложение не принимает подключений
Права в базеправо SELECT на три представленияприложение выполняет к базе только запросы на чтение
Права в Windowsлокальный администратор на машине с приложениемустановка, регистрация службы и управление ею
Роль в UnSpotВладелец или Администратор интеграцийсоздание токена SCIM 2.0 и токена «Импорт расписания сотрудника»

О минимальных привилегиях. Пример настройки прав из поставки приложения выдаёт учётной записи службы роли sysadmin и db_owner — для синхронизации этого не требуется. Приложению достаточно права SELECT на три представления, и в промышленной среде права стоит сузить до этого минимума. Ещё лучше не использовать Windows-аутентификацию от NT AUTHORITY\SYSTEM, а завести отдельную учётную запись СУБД только на чтение и указать её в источнике данных.

Отдельно учитывайте объём прав в UnSpot: токен SCIM 2.0 позволяет создавать, изменять и удалять пользователей рабочего пространства, а токен «Импорт расписания сотрудника» — менять статусы в расписании любого сотрудника. Оба лежат на машине с приложением в открытом виде, поэтому машина с адаптером по уровню защиты приравнивается к рабочему месту администратора UnSpot.

Полный список требований к машине, среде выполнения и дистрибутиву — в статье «Настройка синхронизации по ODBC».

Связанные статьи

Оставьте заявку, и мы свяжемся с вами в течение 30 минут.

Loading

Как улучшить работу офиса?

Оставьте контакт - покажем на демо как уйти от таблиц, двойных бронирований и путаницы с рабочими местами.

Loading