Telephone Directory

Телефонный справочник для Active Directory 1570d127f60649578b7039717d99b094.pngДля тех, кто статью читать не захочет, сразу репозиторий на github.

А остальных под катом ждёт бессвязная и бессмысленная история о том, как я дошёл до жизни такой, при помощи node-webkit, написал приложение, которого джва года ждал.Всю свою сознательную жизнь карьеру сисадмина я восхищался Active Directory от MS. И как только появилась такая возможность — внедрил её на предприятии, где работаю.

И понеслось… Я стал интегрировать всё, до чего дотянусь, с AD. Аутентификация прокси, база сотрудников для СКД, Антивирус и т.п. И не хватало мне для счастья телефонного справочника, который бы брал все данные из базы AD. Уже полгода я то и дело мучаю гугл на эту тему, но результаты не утешительные.

Основные требования к такому справочнику:

отдельное portable приложение. Каждый раз натыкаясь на web-based справочник думал «если уж поднимать для этого сервак — то там уже сделаю полноценный корпоративный портал, а сейчас мне нужен всего лишь маленький справочник. бесплатный Максимально простой и удобный в использовании. Он всегда представлялся мне просто таблицей с сортировкой и поиском Из всего зоопарка подобного софта, что я обнаружил, можно выделить несколько типов:

Громоздкие: Всякие корпоративные порталы jomportal, onlyoffice… Платные: В принципе то, что нужно от dovestones, от ithicos… Имеющие фатальный недостаток: от gourami (стрёмный, не запустился, ещё и фремиум), от dmtsoft (один из лучших, о его недостатках чуть ниже.), или тысяча всевозможных VB скриптов генерирующих HTML файл. Видел когда-то ещё и серверный вариант на php, правда не нашёл его при написании статьи. Его можно отнести к 3-ей группе, так как требование сервера для меня является недостатком.По поводу справочника от dmsoftВыглядит он вот так51e3c3fab4444c6fbc80a3fe020dcc20.pngИ нет никакой возможности хотя бы ширину столбца телефона сделать больше по умолчанию. А настраивать интерфейс каждый раз при запуске жутко раздражает. Ничего не предвещало беды решения этой проблемы, но позавчера я узнал о node-webkit! 3b9e80273e8f4bdc8edacb56dbd2aa01.gifВозможность написания десктопного приложения на знакомом языке — что может быть лучше? Радости моей не было предела.Но вот незадача… Дома маленький ребёнок, постоянно требующий внимания, а на работе внезапно работа. Кодить категорически некогда и негде.Но судьба была ко мне благосклонна — днём воскресенья ребёнок решил поспать. Жена, видимо вспомнив мои восторженные вопли о том, как крут node-webkit, и разгадав мои тайные желания, в ответ на вопрос «чем займёмся, пока дитё спит?»f54ddbf5bd8e4404ad1742babddbdeb4.gifответила «ну ладно… иди уже программируй«Эпизод 1: Марш-бросок до прототипа И так. У меня есть 1.5 — 2 часа на то что бы освоить новую технологию (даже две, так как nodejs я тоже, по сути, не знал) и написать с её помощью софт, который почему-то никто из опенсорс программистов до сих пор не написал.Первым делом — спросил гугл насчёт связи nodejs с ActiveDirectory. Он подсказал целых два модуля: node-activedirectory и ldapjs. Разбираться, что к чему времени не было, так что выбор пал на первый.

КОД var ActiveDirectory = require ('activedirectory'); var ad = new ActiveDirectory ('ldap://example.com', 'dc=example, dc=com', 'superadmin', 'pass');

var groupName = 'Employees'; ad.getUsersForGroup (groupName, function (err, users) { if (err) { console.log ('ERROR: ' +JSON.stringify (err)); return; }

if (! users) console.log ('Group: ' + groupName + ' not found.'); else { console.log (users); } }); Кстати насчёт var groupName = 'Employees'; EMPLOYEES — группа в которую входят все текущие сотрудники РЕЗУЛЬТАТ ERROR: {«dn»:», «code»:49, «name»: «InvalidCredentialsError», «message»:»80090308: LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error, data 52e, v1db0\u0000»} мда… Попытка потыкать второй модуль привела к тому же результату, но за большее время. Курение манов, пинание знакомого nodejs-ника и шальная удача таки дали результат: суперадмин домена почему-то не аутентифицируется, а вот бесправный юзверь, созданный ради гостевого интернета, — сработал! УРА47ca1a0fe92c4034bd435efac2c8e188.png

Времени на разбирательства с правами нету — поехали дальше.

git init Лицензия грязный хак для дебаггинга require ('nw.gui').Window.get ().showDevTools (); копипаст старого кода ВУАЛЯ4082490da0614b5c8ce58519faee2106.png

Можно начинать творить магию… Но уже прошёл почти час. Ребёнок может проснуться в любую минуту. Нет времени на магию — берём всё готовое.Быстрый гуглинг выдал на-гора отличный скрипт для работы с таблицей TinyTable. Копипащу его целиком с примером к себе.Чуть чуть кода var ad = new ActiveDirectory (credentials.dn, credentials.dc, credentials.user, credentials.pass, {attributes: {user: [ 'cn', 'telephonenumber', 'mail' ]}}); // поменял эту строчку что бы доставало только ФИО телефон и мыло

function users2table (users) { tablehtml = ''; for (i in users) { var user = users[i]; console.log (user); tablehtml+=''; tablehtml+= ''+user.cn+'' tablehtml+= ''+user.telephoneNumber+'' tablehtml+= ''+user.mail+'' tablehtml+='' } console.log (tablehtml); $('#table tbody').html (tablehtml); sorter.init (); } ТАДАМe3664e52430c4a469b73567f2c8744b2.png

Из кроватки раздался радостный плачь.Эпизод 2: Утренний кофе На часах 6:50 у меня примерно 20 минут…Убираем адресную строку и называем окошко package.json «window»: { «title»: «Telephone Directory», «toolbar»: false } Автофокус на поле поиска users2table $('#query').focus (); добавляем отдел в таблицу, а точнее — забираем не что попало, а только ФИО, телефон, емэйл, отдел Скрытый текст var ad = new ActiveDirectory (credentials.dn, credentials.dc, credentials.user, credentials.pass, {attributes: {user: [ 'cn', 'telephonenumber', 'mail', 'department']}}); tablehtml+= ''+user.department+'' И раскрываем окно на весь экран, чтобы не париться по поводу размеров Скрытый текст require ('nw.gui').Window.get ().maximize (); Уже весьма неплохо722863b7b29f47908b137ff3d4fb3371.png

Но уже 7:30 и мне пора бежать.Эпизод 3: Наводим марaфет Во время обеда я снова вернулся к коду.Первым делом добавил фичу, которую обдумывал всю дорогу на работу — кеширование. Ибо каждый раз ждать загрузки (пусть и всего несколько секунд) глядя на пустое окно — раздражает.КОД в событие получения ответа от ldap поменял это: users2table (users); на это: var localusers = localStorage.users; var ldapusers = JSON.stringify (users); if (localusers!= ldapusers) {localStorage.users = JSON.stringify (users)} else {console.log ('users didn\'t changed')}; users2table (JSON.parse (localStorage.users)); , а так же добавил в пустое место в скрипте подгрузку с localstorage если не пустой if (localStorage.users) users2table (JSON.parse (localStorage.users)); Пофиксил пару багов, причесал, добавил mailto ссылки для емейлов… В принципе всё. ГОТОВО! 5388881c9346474ba27bcc781cc095aa.png

Как раз и обед закончился.Но данный функционал уже полностью покрывает все мои планы, так что на этом я пока и остановился.Установка поставьте node-webkit скачайте релиз поместите файл private.js содержание module.exports = { dn: «ldap://example.com» , dc: «dc=example, dc=com» , user: «user» , pass: «pass» }; запускайте path\to\nodewebkit\nw.exe path\to\telephone-directory Распространение Запакуйте каталог telephone-directory в .zip Переименуйте архив в .nw Немного магии copy /b path\to\nodewebkit\nw.exe+path\to\telephone-directory telephone-directory.exe докиньте все остальные файлы из node-webkit кроме nw.exe в каталог с telephone-directory.exe Должно получиться так: c553753903fc416c8ed2ed6c7392d3a0.pngВсё — можно выкладывать на сетевой диск или распространять так, как вам вздумаетсяP.S. Код писался впопыхах, так что не блещет красотой. Многие вещи можно и нужно дорабатывать. Но без помощи сообщества я вряд ли буду делать что-то большее чем то, что уже есть. Ибо то, что уже есть — работает и полностью удовлетворяет требованиям —, а большего и не надо.P.P. S. Приложение рассчитано на контору с около 100 сотрудниками (вроде той в которой я работаю). При меньшем количестве вряд ли используется AD. А при большем — может потребоваться какая-то оптимизация кода, но наверняка уже используется корп-портал или что-то подобное.P.P. P.S. Кода 45 строк, так что уверен, даже для сисадминов не знающих JS, подгонка проекта под свои нужды не составит труда.

© Habrahabr.ru