ログイン通知メール機能を追加するRedmineプラグインを作りました。【Redmine Notify Login plugin】
Redmineのセキュリティ向上のためにログインした際に通知メールを飛ばすような機能が欲しいと思ってそういうプラグインが無いか調べてみましたが、
2段階認証をするようなプラグインくらいしか見つからなかったので作ってみました。
■Redmine Notify Login plugin
https://github.com/forest-soft/redmine_notify_login
■イメージ図
Redmineの公式にプラグイン作成のチュートリアルがあるのでこれを読めば簡単なものは作れるようになります。
https://www.redmine.org/projects/redmine/wiki/Plugin_Tutorial
ログイン完了時(2要素認証完了時含む)にうまく処理を差し込めるところが無いかRedmine本体のソースを見ていたところ、
ちょうどよさそうな仕掛けがあることに気づきました。
■/app/controllers/account_controller.rb
def successful_authentication(user)
logger.info "Successful authentication for '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}"
# Valid user
self.logged_user = user
# generate a key and set cookie if autologin
if params[:autologin] && Setting.autologin?
set_autologin_cookie(user)
end
call_hook(:controller_account_success_authentication_after, {:user => user})
redirect_back_or_default my_page_path
end
「アカウント認証が成功した後」のフックを呼び出す・・・という処理です。
Redmineのwikiを見ると
https://www.redmine.org/projects/redmine/wiki/Hooks_List
という感じで便利なフックがいろいろ用意されているみたいなので、今回はフックを使って通知メール送信処理を組み込むことにしました。
フックを使ったチュートリアルは
https://www.redmine.org/projects/redmine/wiki/Plugin_Tutorial#Using-hooks
です。
作り方はチュートリアルのまんまですが、メモしておきます。
1. プラグイン用のフォルダを作る。
今回の場合は「redmine_notify_login」という名前で用意した。
2. プラグインフォルダ直下に「lib」フォルダを作る。
{ROOT}
∟redmine_notify_login
∟lib
3. libフォルダ内にフックを実装するためのファイルを作成する。
今回の場合は「notify_login_hook_listener.rb」というファイル名で用意した。
{ROOT}
∟redmine_notify_login
∟lib
∟notify_login_hook_listener.rb
4. Redmine::Hook::ViewListenerを継承したクラスを作り、フックしたいメソッドと同じ名前のクラスメソッドを作る。
今回使いたいフックは「controller_account_success_authentication_after」なので、この名前でクラスメソッドを作る。
■notify_login_hook_listener.rb
class NotifyLoginHookListener < Redmine::Hook::ViewListener
def controller_account_success_authentication_after(context)
// 実処理
end
end
5. フックメソッド内にログイン通知メール送信処理を実装する。
Redmineで2要素認証を設定したときに「2要素認証を設定しましたよ」という通知メールが飛んできていたので、
その処理を参考にさせてもらうことにした。
処理を見てみると、
■/lib/redmine/twofa/base.rb
def deliver_twofa_paired
::Mailer.security_notification(
@user,
User.current,
{
title: :label_my_account,
message: 'twofa_mail_body_security_notification_paired',
# (mis-)use field here as value wouldn't get localized
field: "twofa__#{scheme_name}__name",
url: {controller: 'my', action: 'account'}
}
).deliver
end
という感じでメールを送信する処理が書かれていたのでこれを拝借させてもらって、
■notify_login_hook_listener.rb
class NotifyLoginHookListener < Redmine::Hook::ViewListener
def controller_account_success_authentication_after(context)
::Mailer.security_notification(
context[:user],
User.current,
{
title: :label_my_account,
message: 'notify_login_mail_body',
url: {controller: 'my', action: 'account'}
}
).deliver
end
end
という感じでメール送信処理を作った。
messageキーに指定している「notify_login_mail_body」は多言語化ファイルのキーなので、後ほどメール本文を用意する。
6. プラグインフォルダ直下に「init.rb」を作る。
{ROOT}
∟redmine_notify_login
∟lib
∟notify_login_hook_listener.rb
∟init.rb
■init.rb
require 'redmine'
require_dependency 'notify_login_hook_listener'
Rails.application.config.i18n.load_path += Dir["#{File.dirname(__FILE__)}/config/locales/*.{rb,yml}"]
Redmine::Plugin.register :redmine_notify_login do
name 'Redmine Notify Login plugin'
author 'Forest Soft'
description 'ログイン通知メールを送信できるようになります。'
version '1.0.0'
url 'https://github.com/forest-soft/redmine_notify_login'
author_url 'http://forest-soft.net'
end
重要なのは
「4.」で作ったファイルを「require_dependency 'notify_login_hook_listener'」で読み込んで、
その次の行の「Rails.application.config.i18n.load_path += Dir["#{File.dirname(__FILE__)}/config/locales/*.{rb,yml}"]」で自前で作った多言語化ファイルを読み込むところの2点。
7. プラグインフォルダ直下に「config」フォルダを作り、その下に「locales」フォルダを作る。
{ROOT}
∟redmine_notify_login
∟config
∟locales
∟lib
∟notify_login_hook_listener.rb
∟init.rb
8. localesフォルダ配下に多言語化ファイルを作り、メールの内容を書く。
{ROOT}
∟redmine_notify_login
∟config
∟locales
∟en.yml
∟ja.yml
∟lib
∟notify_login_hook_listener.rb
∟init.rb
■en.yml
en:
notify_login_mail_body: You have logged in. If you do not remember it, please contact the administrator.
■ja.yml
ja:
notify_login_mail_body: ログインが行われました。身に覚えのない場合は管理者へ連絡してください。
9. 作成したプラグインフォルダをRedmineのpluginsフォルダに配置し、Redmineを再起動する。
これで作成したプラグインが読み込まれているはずなので、後はログインして通知メールが飛んでくれば完成。
2要素認証を有効にしつつログイン通知メールを飛ばすようにすればアカウントを乗っ取られてしまった場合でも気づくことができるので、
これでセキュリティを向上させることができます。
プラグインを探してもいまいち見つからなかったり、Redmine本体に2要素認証が実装されたのにログイン通知メール機能が搭載されないという事は需要があんまりないのかもしれませんが、
無ければ作って継ぎ足せる懐の深さがRedmineのイイところですね!