...

вторник, 3 марта 2015 г.

Telephone Directory

Телефонный справочник для Active Directory





Для тех, кто статью читать не захочет, сразу репозиторий на github.


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

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


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


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



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

  2. бесплатный

  3. Максимально простой и удобный в использовании. Он всегда представлялся мне просто таблицей с сортировкой и поиском


Из всего зоопарка подобного софта, что я обнаружил, можно выделить несколько типов:



  • Громоздкие: Всякие корпоративные порталы jomportal, onlyoffice...

  • Платные: В принципе то, что нужно от dovestones, от ithicos...

  • Имеющие фатальный недостаток : от gourami(стрёмный, не запустился, ещё и фремиум), от dmtsoft(один из лучших, о его недостатках чуть ниже.), или тысяча всевозможных VB скриптов генерирующих HTML файл.


Видел когда-то ещё и серверный вариант на php, правда не нашёл его при написании статьи. Его можно отнести к 3-ей группе, так как требование сервера для меня является недостатком.
По поводу справочника от dmsoft
Выглядит он вот так



И нет никакой возможности хотя бы ширину столбца телефона сделать больше по умолчанию. А настраивать интерфейс каждый раз при запуске жутко раздражает.




Ничего не предвещало беды решения этой проблемы, но позавчера я узнал о node-webkit!



Возможность написания десктопного приложения на знакомом языке — что может быть лучше? Радости моей не было предела.

Но вот незадача… Дома маленький ребёнок, постоянно требующий внимания, а на работе внезапно работа. Кодить категорически некогда и негде.

Но судьба была ко мне благосклонна — днём воскресенья ребёнок решил поспать. Жена, видимо вспомнив мои восторженные вопли о том, как крут node-webkit, и разгадав мои тайные желания, в ответ на вопрос „чем займёмся, пока дитё спит?“



ответила „ну ладно… иди уже программируй“

Эпизод 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-ника и шальная удача таки дали результат: суперадмин домена почему-то не аутентифицируется, а вот бесправный юзверь, созданный ради гостевого интернета, — сработал!

УРА



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



  1. git init

  2. Лицензия

  3. грязный хак для дебаггинга

    require('nw.gui').Window.get().showDevTools();


  4. копипаст старого кода



ВУАЛЯ





Можно начинать творить магию… Но уже прошёл почти час. Ребёнок может проснуться в любую минуту. Нет времени на магию — берём всё готовое.

Быстрый гуглинг выдал на-гора отличный скрипт для работы с таблицей 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+='<tr>';
tablehtml+= '<td>'+user.cn+'</td>'
tablehtml+= '<td>'+user.telephoneNumber+'</td>'
tablehtml+= '<td>'+user.mail+'</td>'
tablehtml+='</tr>'
}
console.log(tablehtml);
$('#table tbody').html(tablehtml);
sorter.init();
}




ТАДАМ



Из кроватки раздался радостный плачь.

Эпизод 2: Утренний кофе




На часах 6:50 у меня примерно 20 минут…

  1. Убираем адресную строку и называем окошко
    package.json


    "window": {
    "title": "Telephone Directory",
    "toolbar": false
    }




  2. Автофокус на поле поиска
    users2table


    $('#query').focus();




  3. добавляем отдел в таблицу, а точнее — забираем не что попало, а только ФИО, телефон, емэйл, отдел
    Скрытый текст


    var ad = new ActiveDirectory(credentials.dn, credentials.dc, credentials.user, credentials.pass, {attributes: {user: [ 'cn', 'telephonenumber', 'mail', 'department']}});



    tablehtml+= '<td>'+user.department+'</td>'




  4. И раскрываем окно на весь экран, чтобы не париться по поводу размеров
    Скрытый текст


    require('nw.gui').Window.get().maximize();






Уже весьма неплохо



Но уже 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 ссылки для емейлов… В принципе всё.

ГОТОВО!



Как раз и обед закончился.

Но данный функционал уже полностью покрывает все мои планы, так что на этом я пока и остановился.

Установка





  1. поставьте node-webkit

  2. скачайте релиз

  3. поместите файл private.js
    содержание


    module.exports = {
    dn:"ldap://example.com"
    ,dc:"dc=example,dc=com"
    ,user:"user"
    ,pass:"pass"
    };




  4. запускайте

    path\to\nodewebkit\nw.exe path\to\telephone-directory



Распространение





  1. Запакуйте каталог telephone-directory в .zip

  2. Переименуйте архив в .nw

  3. Немного магии

    copy /b path\to\nodewebkit\nw.exe+path\to\telephone-directory telephone-directory.exe


  4. докиньте все остальные файлы из node-webkit кроме nw.exe в каталог с telephone-directory.exe




Должно получиться так:



Всё — можно выкладывать на сетевой диск или распространять так, как вам вздумается

P.S.


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

P.P.S.


Приложение рассчитано на контору с около 100 сотрудниками (вроде той в которой я работаю). При меньшем количестве вряд ли используется AD. А при большем — может потребоваться какая-то оптимизация кода, но наверняка уже используется корп-портал или что-то подобное.

P.P.P.S.


Кода 45 строк, так что уверен, даже для сисадминов не знающих JS, подгонка проекта под свои нужды не составит труда.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий