Как стать автором
Поиск
Написать публикацию
Обновить

Telephone Directory

Время на прочтение5 мин
Количество просмотров59K

Телефонный справочник для 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, подгонка проекта под свои нужды не составит труда.
Теги:
Хабы:
Всего голосов 21: ↑20 и ↓1+19
Комментарии31

Публикации

Ближайшие события