Блог Мазепина Василия

Пишу о том, что кажется интересным

Hello, Огнелис ))

2015-05-30 22:33 | Комментарии

Доброго времени суток, коллеги и гости..

Как то на моей нынешней работе стал замечать одно маленькое неудобство.
Данные для входа в одну нашу инфраструктурную систему(а она в web-формате) в целях безопасности меняются определенный период времени, и приходится постоянно обращаться за новыми данными в Redmine.
И в общем то один из моих коллег решил написать приложение для Google Chrome, которое бы при необходимости заполняла бы поля для входа, и автоматически бы производила вход. Согласитесь, удобно))
И в общем то, такое приложение написано было, однако в нем был один фатальный недостаток - я не пользуюсь этим браузером.
Поэтому, мною было принято решение написать подобное расширение для firefox. Я начал изучать документацию и возможность реализации.
И вот как всё было. (https://developer.mozilla.org/ru/Add-ons)[На странице по разработке расширений] я узнал, что существуют два основных способа написания расширений:

  • Разработка расширения с помощью набора высокого уровня JavaScript API.
  • Наложения XUL

При этом Наложения XUL морально устарело. Ок, Вася, пишем на высоком уровне JavaScript API.
Суть приложения такова - при загрузке браузера, в память будет записаны данные, необходимые для входа, и при обращении на страницу входа в нашу систему, данные будут вставлены и осуществлен вход. Итак, начнем:
Нам необходимы:

  • Python 2.5 - 2.7.
  • Сам Firefox(у меня на момент написания была 34 версия)
  • SDK

Скачиваем необходимый SDK, с помощью которого мы будем разрабатывать наше расширение, потом

1
2
3
tar -xf addon-sdk.tar.gz
cd addon-sdk
source bin/activate

После этого в том же терминале(это важно, после закрытия терминала пришлось проводить “source bin/activate” заново).

1
2
3
mkdir my-addon #создаем директорию приложения
cd my-addon // Спасаем мир от внепланетной угрозы, попутно перейдя в директорию приложения
cfx init // Инициализируем новое приложение

Мы увидим:
* lib directory created
* data directory created
* test directory created * doc directory created
* README.md written
* package.json written // Здесь запишем настройки приложения
* test/test-main.js written // Тут тесты
* lib/main.js written // Главный файл приложения
* doc/main.md written // Можете написать стишок, но лучше документацию

Запуск приложения:

1
cfx run // И нам откроется браузер с только что установленным нашим расширением

Вот что мы запишем в нашем расширении в файле настроек:

package.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
  "name": "Имя приложения",
  "title": "Заголовок - как его увидит firefox",
  "id": "jid1-71UHEjM9SVvjrA", //Ключ расширения
  "description": "Описание приложения",
  "author": "Mazepin Vasily", //Конечно же я
  "license": "Пират",
  "version": "1.0",
  "preferences": [{
    "name": "url",
    "title": "УРЛ для работы с редмайн",
    "description": "",
    "type": "string",
    "value": "Извиняйте, секрет",
    "hidden": true
  },
  {
    "description": "API Ключ",
    "name": "password",
    "type": "string",
    "value": "",
    "title": "API kлюч redmine"
  }]
}

Тут мы обозначили данные о приложении и поля настроек.
Теперь само приложение, написано очень кратко и просто, однако на написание потребовалось время, дабы изучить документацию.

lib/main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
var Request = require("sdk/request").Request; // Этим мы отправим запрос по API, чтобы узнать данные для входа
var pageMod = require("sdk/page-mod"); А этим обьектом мы прикрепимся к определенным страницам
Request({
    url: require('sdk/simple-prefs').prefs['url'], // Это та самая настройка из package.json
    headers: {
        'X-Redmine-API-Key': require('sdk/simple-prefs').prefs['password'] // И это та самая настройка из package.json
    },
    //Отправляем запрос, и при получении ответа...
    onComplete: function(response) {
        var json = response.json;
        if (json != null) {
            var str = json['wiki_page']['text'];
            var re = /password: {1}([0-9 a-z]{0,12})/i;
            // Выделяем нужные данные
            var password = str.match(re)[1];
            И прикрепляемся к страницам по правилу:
            pageMod.PageMod({
                include: "*.domen.ru",
                //Если это страница входа и есть поле пароля, то пихаем данные из Redmine в форму
                contentScript: "if(location.pathname == '/login') {" +
                "var input = document.getElementById('password');" +
                "var input2 = document.getElementById('username');" +
                "if (input != null) {" +
                "input.value = '" + password + "';" +
                "input2.value = 'mail@retailcrm.ru';" +
                "form = document.getElementsByClassName('login')[0];" +
                "form.submit()" +
                "}" +
                "}",
                contentScriptWhen: "ready"
            });
        } else {
            //Если данные не пришли - даем уведомление. 
            var notifications = require("sdk/notifications");
            notifications.notify({
                title: "API ERROR",
                text: "Не удалось взять данные"
            });
        }

    }
}).get();

И теперь на всех страницах входа для определенного домена будут подставляться данные входа.
В данном случае есть один минус - пароль берется в момент запуска расширения(часто это запуск браузера). В этом случае для обновления пароля надо перезапустить приложение(либо браузер).
Но для меня сейчас это не критично.
Потом планирую улучшить это все и подрефакторить, но пока что отмечаю написание первой версии))
Итак, вследствие огромной лени было создано первое для меня расширение для firefox.

Комментарии