К основному контенту

Синхронизация фоток пользователей в Учетные записи Active Directory

Занимательные взаимоотношения получились с задачей обновления фотографий пользователей в учетные записи Active Directory. Все оказалось несколько "необычнее", чем смотрелось на первый взгляд.


Подход к снаряду №1. Разминочный
Фотография (аватар) хранится в АДшной записи в поле thumbnailPhoto. Размер фотографии в целом ограничен только ее объемом: 100КБ в jpeg формате.
Как выяснилось, "запихивают" туда фотографию нужно через поток:
Set adoStreamRead = CreateObject("ADODB.Stream")

adoStreamRead.Type = 1
adoStreamRead.Open
adoStreamRead.LoadFromFile(ПУТЬ_К_ФАЙЛУ)
adUser.put "thumbnailPhoto", adoStreamRead.Read()

adUser.setInfo
adoStreamRead.Close
Вроде все ок, да?

Подход к снаряду №2. "Не хочешь по-хорошему - заставим"
Оказывается нет, по крайней мере, если дело касается Notes/DominoadoStreamRead.Read() в выше описанном коде возвращает массив байт. Даже, если любая фотография укладывается в ограничения АД - 100КБ, то исходя из ограничений размерности массива в лотусе, получим, что максимально можем считать только 64КБ. И это при условии установления значения первого индекса в массиве на -32768.
Ок. Возвращаясь к методу adoStreamRead.Read(), в качестве параметра можно указать размер буфера. НО. Даже если считывать порционно:
1. Дописывать в атрибут объекта в АД возможности нет (если только он не многозначный, но это не наш случай)
2. Где-то на просторах Интернета промелькнула информация, что можно перевести массив байт в Base64, но при попытке запихнуть их атрибут, AD выдает ошибку.
В целом, подход записи через поток подходит, но только если фотографии не превышают 32КБ. Можно пойти по этому пути и, например, используя WIA уменьшать фотографию на лету до того размера и качества, которое будет влезать в 32КБ.

Подход к снаряду №3. Завершающий. "В любом случае заставим"
Вставить фотографию можно одной единственной строчкой PowerShell скрипта, вида:
Set-ADUser ЛОГИН_ПОЛЬЗОВАТЕЛЯ -Replace @{thumbnailPhoto=[byte[]](Get-Content ПУТЬ_К_ФОТО -Encoding byte)}
Основное требование в 100КБ остается, но никаких 32КБ нас уже не волнуют. Так и было решено. В качестве параметров, в скрипт можно передавать логин пользователя, путь к фотке. так же Set-ADUser может быть запущен из-под указанных учетных данных (-Credential), например так:
$login = "ЛОГИН_УЧЕТКИ_ДЛЯ_ИЗМЕНЕНИЙ"
$pass = ConvertTo-SecureString "ПАРОЛЬ_УЧЕТКИ_ДЛЯ_ИЗМЕНЕНИЙ" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($login, $pass)
Set-ADUser ЛОГИН_ПОЛЬЗОВАТЕЛЯ -Replace @{thumbnailPhoto=[byte[]](Get-Content ПУТЬ_К_ФОТО -Encoding byte)} -Credential  $cred
Через shell запускаем powershell.exe с путем к скрипту и нужными параметрами. На всякий случай в скрипте лучше вызвать import-module activedirectory

Комментарии

Популярные сообщения из этого блога

Занимательные алгоритмы. Поиск цикла в односвязном списке

И снова про тараканов, которые иногда возникают в голове. Как-то раз, засыпая, я задумался на курьезными задачками из своей сферы деятельности (Lotus Notes), которые можно было бы задать на собеседовании, плавно перешел к воспоминаниям о своих первых собеседования, когда опыта работы еще не было. Опыт самих собеседований у меня не велик а места, где задавались действительно интересные задачи (а не задачки типа: написать сортировку массива любым известным способом) вообще равны одному - это ABBYY. Как минимум одна задачка в списке на знание и понимание классических алгоритмов, описанных в книге Дональда Кнута -  Искусство программирования .

Unit-testing object validation when validator has DI

Summary Unit test object validation when validator(s) has a dependency. For instance, we have some custom field and cross-field validators. Want to test their combination. Additionally some of validators have dependencies, injected through constructor or setters. You're not using property injection, right? Shortcut If you are just searching for an answer, here's the fast way: Declare CustomConstraintValidatorFactory that implements javax.validation.ConstraintValidatorFactory Override getInstance method and on facing your constraint validator class instantiate it Otherwise delegate validator construction to org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorFactoryImpl Build validator factory and provide it your CustomConstraintValidatorFactory Build validator, using that factory... Go to demo project on GitHub for details:  https://github.com/MrArtemAA/blog-demos/blob/master/test-validator-with-injection/src/test/java/ru/artemaa/d

Lotus Notes FAQ. 8/9 Eclipse. Как настроить уведомления о Sametime сообщениях

Н а написание данной "инструкцию" натолкнул мой коллега. Помню, первый раз сам долго искал, как отключить постоянно выпрыгивающие уведомления о новых сообщениях в Sametime. И так, речь идет о клиентах IBM Notes 8+ версии Standart (Eclipse based). Как настроить уведомления о Sametime сообщениях?