この記事はtraP夏のブログリレー4日目の記事です。
こんにちは、logicaです。昨日までセキュキャンに参加させていただいており、体力的には満身創痍の状態でこの記事を書いています。
マジでキツかったけど、開講中はアドレナリンドバドバでした。無事倒れずに完走できてよかった。
というわけで今回は、僕が今メインメンテナーを務めるtraQという部内メッセージングサービス(詳しくはリンクへ)に寄せられた、とあるバグ報告とそれを解決するまでの流れを皆様に紹介したいと思います。
目次
ex-traP、ex-traQという存在
traPには、ex-traPと呼ばれるOB・OG会があります。
現時点では院まで卒業した15B・16Bの世代が主なメンバーで、たまに会ったりゆるーく雑談したりしています。
そんなex-traP、コミュニケーションに用いているのは...もちろんtraQ!
traQのソースコードをコピーして本家traQとは別の場所で動かしており、ex-traQという愛称が付けられています。
そんなex-traQですが、次のような場合、現役生も自由に参加することができます。
- 役員として、OB・OGと連絡を取らなければいけない
- 単純にOB・OGとコミュニケーションが取りたい
- OB・OGの現在に興味がある
僕はコミュニケーションが取りたいな〜と思って参加し、たまにOB・OGとわいわいしてます。
バグ報告が来た
ex-traQを徘徊していたとある午後のこと、こんなメッセージが投稿されているのを見つけました。
卒業生はtraPを引退するとき、traQアカウントの凍結という作業を行います。ユーザーとしてのデータは残りますが、ログインや閲覧など全ての操作ができなくなります。
少なくとも、そのはずでした。
ですが、これを見る限り、引退してtraQから凍結された人間に本家traQの通知がガッツリ飛んでいます。
こんな報告が飛んで来たら、traQメンテナーとしてやることはただ一つですね。
直します。
原因を探る
とりあえず報告
報告してくれたOrangeStarさんに調査する旨を伝え、共にtraQをメンテナンスしている仲間とこの情報を共有します。
原因となったメッセージを特定
幸いOrangeStarさんがスクリーンショットを貼って下さっていたので、それらしいメッセージはすぐに発見できました。
該当するコードを見つける
なぜ通知が飛んだのか整理する
traQでは、相手に通知が飛ぶ条件がいくつかあります。
- 通知を付けたチャンネルにメッセージが投稿されたとき
- これがメイン
- 自分がメンションされたとき
@{ユーザー名}
で相手に通知が飛ばせる
- 自分の投稿が引用されたとき
- メッセージに、他のメッセージのリンクを記載することで「引用投稿」ができる
- 引用された投稿の投稿者に通知が飛ぶ
今回は、OrangeStarさんの投稿が引用されたことで、引用投稿の通知が飛んでいますね。
コードを読む
頑張ってコードの流れを追い、引用通知対象者を見つける箇所を見つけました(リンク先は当時のコード)。
メンション通知対象者を見つける部分は、次のようになっています(わかりやすさのため一部改変)。
// メンションユーザー取得
for _, uid := range parsed.Mentions {
user, err := ns.repo.GetUser(uid, false)
if err != nil {
logger.Error("failed to GetUser") // 失敗
continue
}
// 凍結ユーザーの除外
if !user.IsActive() {
continue
}
notifiedUsers.Add(uid)
markedUsers.Add(uid)
noticeable.Add(uid)
}
一方、引用通知対象者を見つける部分は、次のようになっていました(わかりやすさのため一部改変)。
// メッセージを引用されたユーザーへの通知
for _, mid := range parsed.Citation {
m, err := ns.repo.GetMessageByID(mid)
if err != nil {
logger.Error("failed to GetMessageByID") // 失敗
continue
}
uid := m.UserID
markedUsers.Add(uid)
noticeable.Add(uid)
citedUsers.Add(uid)
}
さあ、勘のいいあなたならもうお気づきですね?
そうです、メンション通知では存在する「凍結ユーザーの除外」のコードが、引用通知では存在しないのです!
という感じでバグっている箇所が発見できたので、もうバグ修正は8割完了したようなものです。
修正する
修正しました。修正したコミットはこちら。
こんな感じの処理を挟むだけです。
Botに対しても通知を飛ばそうとしてしまっていたことが明らかになったので、それも含めてプルリクエストを出し、他のtraQメンテナーに確認してもらいます。
承認をもらったらマージし、新バージョンとしてリリースして修正完了です!
普段リリースはもう少し改善・修正が溜まって、十分確認してからやることが多いですが、今回のバグは情報漏洩に繋がる結構重大なバグだったので緊急性が高いと判断し、すぐにリリースし本番環境に適用しました。
バグ報告を発見してからここまで、大体12時間くらいで対応できました。
バグ発見者に報告
OrangeStarさんにバグ修正を報告して、メンテナーとしてやる事は全て完了です!
おわりに
今日はtraQメンテナーの普段のお仕事を紹介してみました。
traQメンテナーたちは、学業で忙しい合間を縫ってですが、こんな感じでバグ修正や機能改善をしています。
バグ修正については特に原因の特定作業が大変ですが、修正完了後にユーザーから喜んでもらえるのが何よりの喜びです。
みなさんもこれを見て「サービスの運営って楽しそうだな」と少しでも思ってもらえたら嬉しいです!
それでは、またどこかでお目にかかりましょう。logicaでした!
夏のブログリレーはまだまだ続きます! 明日の担当はsabanishi君です。楽しみ~