- PVSM.RU - https://www.pvsm.ru -
Некоторое время назад мы рассказывали о том, как в Mail.Ru реализован сбор почты с использованием протокола OAuth 2.0 [1]. Мы продолжаем повышать безопасность почты и продвигать стандарт OAuth 2.0 в массы. И сегодня расскажем о том, как мы добавили OAuth-авторизацию в почтовый клиент Mozilla Thunderbird. На этом примере мы разберем процесс внесения новой фичи в продукт с открытым исходным кодом, от создания тикета до релиза. Если вы давно хотели сделать свой первый pull request, но не знали как, — читайте нашу историю.
На действия пользователя Thunderbird открывает веб-вью с адресом для OAuth-авторизации. Если пользователь успешно прошел процедуру авторизации и согласился предоставить приложению доступ к своим данным, то мы перенаправляем пользователя на адрес, указанный в параметре redirect_uri
. Так приложение получит авторизационный токен и сможет использовать его для работы с нашей почтовой службой. Адрес для запроса токена:
https://o2.test.mail.ru/login
?response_type=code
&client_id=<идентификатор приложения>
&redirect_uri=http%3A%2F%2Flocalhost
Стоит заметить, что значение localhost
для параметра redirect_uri
приложение задает самостоятельно, а параметр state [2] (используется клиентом для поддержки связи между запросом и колбэком) не передает вовсе. Ниже представлена схема взаимодействия приложения с сервисом:
Хотя сам процесс интеграции довольно простой и не занимает много времени, все же стоит рассказать об отдельных моментах, которые следует планировать заранее.
Поскольку Thunderbird — это продукт компании Mozilla, мы сразу отправились на MDN [3]. Так мы быстро получили общее представление об основных этапах интеграции:
Далее рассмотрим каждый этап в отдельности.
Перед тем как ставить тикет, убедитесь, что до вас этого никто не сделал. Постановка тикета является ключевым этапом в решении любой похожей задачи, поэтому очень важно правильно заполнить все обязательные поля:
Продукт: Структура репозитория comm-central
разделена на независимые продукты. С этим у нас проблем не возникло, поскольку название продукта MailNews
сразу упоминается на стартовой странице [3].
Компонент: Напротив этого пункта есть подсказка, однако здесь и так интуитивно понятно, что работа связана с сетью, поэтому выбираем Networking.
Версия: Чтобы понять, какую версию релиза выбрать, следует обратиться к странице со списком релизов [4]. Однако этой информации будет явно недостаточно, поскольку нам важно понимать, на каком этапе находится еще не вышедший релиз. С этим нам поможет календарь [5] релизов. Более подробную информацию о релиз-цикле можно получить на соответствующей странице [6]. Но если вы все-таки сомневаетесь, какую версию релиза выбрать, то не стесняйтесь задать свой вопрос в списке рассылок [7] или IRC-канале [8]. При крайней необходимости вам помогут ревьюверы тикета.
Платформа: В нашем случае продукт платформонезависимый (all
).
Важность: Поскольку мы расширяем функциональность, тип будет enhancement
.
feature
, user-doc-needed
.Совет: чтобы случайно не пропустить какой-либо этап, добавьте к себе календарь [9].
Нам попался хороший ревьювер, который помог с заполнением большинства полей и релизом. Смотрите пример нашего [10] тикета.
comm-central
Если вы обратили внимание, сообщество Mozilla очень трепетно относится к документированию своих продуктов. Руководство по сборке [11] продукта, стилистике [12] написания программного кода и пр. Все ссылки на это располагаются в одном месте и не требуют, как это часто бывает с другими продуктами, прохождения некоего квеста. Сразу скажу, что никакого "rocket science" в добавлении нового OAuth-провайдера в Thunderbird нет, — это становится понятно после грепа по репозиторию [13] и беглого ознакомления с исходным кодом. Несмотря на то что файлов с ключевым словом OAuth было довольно много:
➜ hg clone http://hg.mozilla.org/comm-central
...
➜ hg grep --ignore-case --files-with-matches oauth | wc -l
91
Интуиция подсказывала, что все должно быть проще. И мы не ошиблись, когда открыли первый из списка файл:
mailnews/base/util/OAuth2Providers.jsm
Не буду томить, просто смотрите дифф:
➜ hg log -p -l 1
changeset: [draft] 18512:a2f404184ac0 support_oauth_mail_ru_1231642 tip
author: Alexander Abashkin <monolithed@gmail.com>
date: Mon, 14 Dec 2015 15:17:09 +0300 (4 months ago)
summary: Bug 1231642 - Log in to Mail.Ru (IMAP/SMTP) using OAuth
M mailnews/base/util/OAuth2Providers.jsm
diff --git a/mailnews/base/util/OAuth2Providers.jsm b/mailnews/base/util/OAuth2Providers.jsm
--- a/mailnews/base/util/OAuth2Providers.jsm
+++ b/mailnews/base/util/OAuth2Providers.jsm
@@ -10,32 +10,41 @@ var EXPORTED_SYMBOLS = ["OAuth2Providers
var {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
// map of hostnames to [issuer, scope]
var kHostnames = new Map([
["imap.googlemail.com", ["accounts.google.com", "https://mail.google.com/"]],
["smtp.googlemail.com", ["accounts.google.com", "https://mail.google.com/"]],
["imap.gmail.com", ["accounts.google.com", "https://mail.google.com/"]],
["smtp.gmail.com", ["accounts.google.com", "https://mail.google.com/"]],
+ ["imap.mail.ru", ["o2.mail.ru", "mail.imap"]],
+ ["smtp.mail.ru", ["o2.mail.ru", "mail.imap"]],
]);
// map of issuers to appKey, appSecret, authURI, tokenURI
var kIssuers = new Map ([
["accounts.google.com", [
'406964657835-aq8lmia8j95dhl1a2bvharmfk3t1hgqj.apps.googleusercontent.com',
'xxxxxxxxxxxx',
'https://accounts.google.com/o/oauth2/auth',
'https://www.googleapis.com/oauth2/v3/token'
]],
+ ["o2.mail.ru", [
+ 'thunderbird',
+ 'xxxxxxxxxxxx',
+ 'https://o2.mail.ru/login',
+ 'https://o2.mail.ru/token'
+ ]],
]);
Если вы обратили внимание, то, к сожалению, мы пока не поддержали новый протокол [14], который позволяет динамически регистрировать клиент, но мы над этим работаем! И далее аттач патча по номеру тикета:
hg diff -g > 1231642.patch
P. S. Будьте готовы к тому, что клонирование репозитория требует до 5 Гб свободного места на диске.
Эта конфигурация необходима для выбора протокола, который будет использоваться по умолчанию. Пример файла-автоконфига: https://autoconfig.thunderbird.net/v1.1/mail.ru [15]. SNN-репозиторий ISP
находится по следующему адресу:
https://svn.mozilla.org/mozillamessaging.com/sites/autoconfig.mozillamessaging.com/
Поскольку мы уже имели дело с этим конфигом ранее, то показать дифф будет проще, чем рассказать:
➜ svn diff trunk/mail.ru | vi -R -
--- trunk/mail.ru| (revision 150325)
+++ trunk/mail.ru| (working copy)
@@ -13,6 +13,7 @@
<incomingServer type="imap">
<hostname>imap.mail.ru</hostname>
<port>993</port>
<socketType>SSL</socketType>
<username>%EMAILADDRESS%</username>
+ <authentication>OAuth2</authentication>
<authentication>password-cleartext</authentication>
</incomingServer>
<incomingServer type="imap">
<hostname>imap.mail.ru</hostname>
<port>143</port>
<socketType>STARTTLS</socketType>
<username>%EMAILADDRESS%</username>
+ <authentication>OAuth2</authentication>
<authentication>password-cleartext</authentication>
</incomingServer>
<outgoingServer type="smtp">
<hostname>smtp.mail.ru</hostname>
<port>465</port>
<socketType>SSL</socketType>
<username>%EMAILADDRESS%</username>
+ <authentication>OAuth2</authentication>
<authentication>password-cleartext</authentication>
</outgoingServer>
<outgoingServer type="smtp">
<hostname>smtp.mail.ru</hostname>
<port>587</port>
<socketType>STARTTLS</socketType>
<username>%EMAILADDRESS%</username>
+ <authentication>OAuth2</authentication>
<authentication>password-cleartext</authentication>
</outgoingServer>
На этом этапе торопиться не стоит, даже если ваш сервер уже поддерживает OAuth-авторизацию, ведь можно получить сайд-эффект в виде неработающей авторизации. В качестве альтернативы вы можете разместить файл автоконфига на своем сервере:
https://autoconfig.mail.ru/mail/config-v1.1.xml [16]. В таком случае у вашего файла будет более высокий приоритет и вы сможете самостоятельно управлять способом авторизации не только на этапе тестирования. Если у вашего почтового сервиса есть алиасы доменов, то переживать не стоит: ISP-сервер смотрит на MX-записи. Более подробно об этом способе конфигурации сервера смотрите здесь [17].
Клонируем репозиторий:
hg clone http://hg.mozilla.org/comm-central
cd comm-central
python client.py checkout
Добавляем конфигурацию для тестового окружения:
➜ echo $'ac_add_options --enable-application=mailnac_add_options --enable-debug' > .mozconfig
Собираем проект:
./mozilla/mach build
Если во время сборки появится ошибка о том, что исходный код устарел, то выполните следующую команду и перезапустите сборку еще раз:
./mozilla/mach mercurial-setup --update-only
Более подробно о сборке проекта смотрите здесь [11].
Возможные проблемы:
Для OS X
10.9–10.10 (в 10.11 эта опция мешает сборке) может потребоваться добавить следующую опцию:
echo 'ac_add_options --with-macos-sdk=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/'
Также в процессе сборки может возникнуть требование установить autoconf 2.13:
fx-team ./mach build
/usr/bin/make -f client.mk -s
Adding client.mk options from :
MOZ_OBJDIR=/Applications/MAMP/htdocs/fx-team/obj-x86_64-apple-darwin14.0.0
OBJDIR=/Applications/MAMP/htdocs/fx-team/obj-x86_64-apple-darwin14.0.0
/Applications/MAMP/htdocs/fx-team/client.mk:304: *** Could not find autoconf 2.13. Stop.
make: *** [build] Error 2
0 compiler warnings present.
Решение для OS X:
brew rm autoconf
brew tap homebrew/versions
brew install autoconf213
Возможно, это наша вина, но по каким-то причинам файл configure
сгенерировался с синтаксическими ошибками:
0:00.70 *** Fix above errors and then restart with
0:00.70 "/opt/local/bin/gmake -f client.mk build"
0:00.71 /comm-central/client.mk:361: ошибка выполнения рецепта для цели «configure»
0:00.71 gmake[1]: *** [configure] Ошибка 1
Решение:
rm configure && ./mozilla/mach build
Такая ошибка свидетельствует об отсутствии в системе компилятора YASM.
0:09.52 configure:21252: checking for CoreMedia/CoreMedia.h
0:09.52 configure:21262: /usr/bin/clang -E -Qunused-arguments conftest.c >/dev/null 2>conftest.out
0:09.52 configure: error: yasm is a required build tool for this architecture when webm is enabled. You may either install yasm or --disable-webm (which disables the WebM video format). See https://developer.mozilla.org/en/YASM for more details.
0:09.52 *** Fix above errors and then restart with
0:09.52 "/opt/local/bin/gmake -f client.mk build"
0:09.52 /comm-central/client.mk:361: ошибка выполнения рецепта для цели «configure»
0:09.52 gmake[1]: *** [configure] Ошибка 1
Решение (для OS X):
brew install yasm && ./mozilla/mach build
Информацию о возможных проблемах сборки можно посмотреть в файле client.mk [18]. Будьте готовы к тому, что исходный код проекта и сборка будет занимать на диске 8,3 Гб!
Запуск проекта:
В конфигурации мы указали ключ --enable-debug
, он поможет нам видеть всю отладочную информацию, включая исходящие запросы к сторонним сервисам.
./mozilla/mach run
Команда run
сама найдет путь к приложению и запустит его. В нашем случае после сборки приложение расположилось по следующему пути:
./obj-x86_64-apple-darwin15.0.0/dist/DailyDebug.app/Contents/MacOS/thunderbird
Автоматизированное тестирование:
Для автоматизации тестирования Thunderbird использует фреймворк MozMill [19] и XPCShell [20]. Запускаем модульные тесты:
./mozilla/mach xpcshell-test
Более подробную информацию о модульном тестировании смотрите ниже по ссылкам:
Запускаем интеграционные тесты:
./build/pymake/make.py mozmill
Для интеграционного тестирования используется фреймворк MozMill [19].
После локального прогона тесты запускает ревьювер, он же и проверяет заявленную функциональность. Как только релиз-инженер включит ваш патч в релиз в Treeherder CI [23], будет запущен цикл регрессионного тестирования. Дополнительную информацию о других видах (например, тестирование на утечки памяти [24]) тестирования смотрите по этой ссылке [25].
Руководство по Treeherder CI смотрите здесь [26].
Как только релиз-инженер включит ваш патч в ранний релиз, вы можете начинать следующий этап тестирования. Согласно рабочему процессу, первым собирается ранний релиз под названием Aurora, далее Beta и релиз. Ссылки на скачивание ранних релизов находятся здесь [27]. Календарь [28] поможет не пропустить важную для вас дату релиза.
Общая схема этапов релиза выглядит так:
Релиз-цикл каждого этапа занимает шесть недель.
Для клиентов, которые еще не обновились до 45-го релиза, должна работать стандартная схема авторизации. И если об этом не подумать заранее, то пользователь всегда будет видеть ошибку авторизации (если вручную не сменит способ авторизации):
Для того чтобы сохранить обратную совместимость, мы стали отдавать конфигурационный файл [16], ориентируясь на User-Agent:
location /mail/config-v1.1.xml {
if ($http_user_agent ~ Thunderbird/(d|[1-3]d|4[0-4]).) {
rewrite config-v1.1.xml /mail/original.config-v1.1.xml;
}
}
Выставляем заголовок Vary: User-Agent [29]
add_header Vary User-Agent;
Теперь пользователи старых клиентов будут получать файл конфигурации без OAuth. Проверяем:
➜ curl 'https://autoconfig.mail.ru/mail/config-v1.1.xml' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 Lightning/4.0.5.2' 2>/dev/null | fgrep -i oauth
➜ curl 'https://autoconfig.mail.ru/mail/config-v1.1.xml' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/45.0.0 Lightning/4.0.5.2' 2>/dev/null | fgrep -i oauth
<authentication>OAuth2</authentication>
<authentication>OAuth2</authentication>
<authentication>OAuth2</authentication>
<authentication>OAuth2</authentication>
Теперь, когда несколько долгих месяцев позади, релиз можно скачивать с главной страницы [30]! Далее мы покажем, что же в итоге увидит пользователь.
Способов добавления почтового аккаунта в Thunderbird несколько, однако все они сводятся к одним и тем же действиям, поэтому рассмотрим самый очевидный:
1. Открываем стартовую страницу. В разделе создания нового почтового аккаунта выбираем Email
:
2. Пропускаем этот шаг, поскольку у нас уже есть почтовый аккаунт:
3. Добавляем почтовый адрес и жмем кнопку «Продолжить»:
4. Выбираем протокол сбора почты (IMAP
) и жмем кнопку «Готово»:
5. На этом шаге проверяем настройки почтового сервера и, если все в порядке, жмем кнопку «Готово»:
6. Вводим авторизационные данные от своей учетной записи в Mail.Ru:
7. Соглашаемся с тем, что Thunderbird
будет собирать почту с нашего аккаунта:
8. Ожидаем, когда письма будут скачаны:
Как видите, мы стараемся развивать не только свои opensource-проекты [31], но и сторонние. Мы крайне щепетильны в вопросах безопасности, поэтому решили подключиться к разработке Mozilla Thunderbird и помочь с реализацией OAuth 2.0. Надеемся, наш пост воодушевит кого-то сделать свой первый pull request, и мир opensource статет чуточку лучше.
Автор: Mail.Ru Group
Источник [41]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/open-source/128468
Ссылки в тексте:
[1] как в Mail.Ru реализован сбор почты с использованием протокола OAuth 2.0: https://habrahabr.ru/company/mailru/blog/264049/
[2] state: https://tools.ietf.org/html/rfc6749#section-4.1.1
[3] MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird
[4] списком релизов: https://www.mozilla.org/en-US/thunderbird/releases/
[5] календарь: https://wiki.mozilla.org/RapidRelease/Calendar
[6] странице: https://wiki.mozilla.org/RapidRelease
[7] списке рассылок: https://lists.mozilla.org/listinfo/dev-apps-thunderbird
[8] IRC-канале: http://irc://irc.mozilla.org/maildev
[9] календарь: https://www.google.com/calendar/ical/mozilla.com_2d37383433353432352d3939%40resource.calendar.google.com/public/basic.ics
[10] нашего: https://bugzilla.mozilla.org/show_bug.cgi?id=1253196
[11] сборке: https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Simple_Thunderbird_build
[12] стилистике: https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Mailnews_and_Mail_code_review_requirements
[13] репозиторию: http://hg.mozilla.org/comm-central
[14] новый протокол: https://tools.ietf.org/html/rfc7591
[15] https://autoconfig.thunderbird.net/v1.1/mail.ru: https://autoconfig.thunderbird.net/v1.1/mail.ru
[16] https://autoconfig.mail.ru/mail/config-v1.1.xml: https://autoconfig.mail.ru/mail/config-v1.1.xml
[17] здесь: https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Autoconfiguration#Configuration_server_at_ISP
[18] client.mk: https://dxr.mozilla.org/mozilla-central/source/client.mk
[19] MozMill: https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Thunderbird_MozMill_Testing
[20] XPCShell: https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Language_bindings/XPConnect/xpcshell/Reference
[21] Инструкция по запуску XPCShell-тестов в продукте MailNews: https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/MailNews_xpcishell-tests
[22] Информация о фреймворке для тестирования AsyncTestUtils: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/MailNews/AsyncTestUtils_Extended_Framework
[23] Treeherder CI: https://treeherder.mozilla.org/#/jobs?repo=comm-central
[24] тестирование на утечки памяти: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/MailNews/Leak_And_Bloat_Tests
[25] ссылке: https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Thunderbird_Automated_Testing
[26] здесь: https://developer.mozilla.org/en-US/docs/Mozilla/Firefox_OS/Automated_testing/Treeherder
[27] здесь: https://www.mozilla.org/en-US/thunderbird/channel/
[28] Календарь: https://calendar.google.com/calendar/embed?src=bW96aWxsYS5jb21fZGJxODRhbnI5aTh0Y25taGFiYXRzdHY1Y29AZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ
[29] Vary: User-Agent: https://varvy.com/mobile/vary-user-agent.html
[30] главной страницы: https://www.mozilla.org/en-US/thunderbird/
[31] opensource-проекты: https://opensource.mail.ru/
[32] Kent James: https://twitter.com/rkentjames
[33] Andrew Sutherland: https://twitter.com/asutherland
[34] OAuth 2.0 простым и понятным языком: https://habrahabr.ru/company/mailru/blog/115163/
[35] Репозиторий ISP: https://svn.mozilla.org/mozillamessaging.com/sites/autoconfig.mozillamessaging.com/
[36] FTP-сервер Thunderbird: https://ftp.mozilla.org/pub/thunderbird/
[37] Багтрекер Bugzilla: https://bugzilla.mozilla.org
[38] Thunderbird API: https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Thunderbird_API_documentation
[39] Документация о репозитории comm-central: https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/comm-central
[40] Каналы связи разработчиков Thunderbird: https://wiki.mozilla.org/Thunderbird/CommunicationChannels
[41] Источник: https://habrahabr.ru/post/282319/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.