Bug(バグ) #1675
完了設定ファイルを記述し忘れた場合に、招待メールに記載されたURLにアクセスできない
100%
説明
http://sns.openpne.jp/communityTopic/6423 より転記
招待メールに記載されたURLにアクセスできません。 <動作環境> OpenPNE3.6beta5 CentOS5(OpenVZの仮想環境) PHP 5.2.11 mysql Ver 14.14 招待状に記載されていたURL http://ドメイン名/member/register/token/3228758dcc32ffb79b61ee61deb73c1b1 実際に利用できた(手で書き換えた)URL http://ドメイン名/sns/web/member/registerInput/token/3228758dcc32ffb79b61ee61deb73c1b1 登録完了メールには以下の正しいURLが記載されていました。 (このURLでOpenPNEにアクセス可能) http://ドメイン名/sns/web/
本チケットで扱う問題¶
note-14 のコメントを以て、
- 「設定ファイルを正しく設定したにもかかわらず、招待メールに記載されたURLにアクセスできない」という報告された問題は「再現せず」と判断する
- 「設定ファイルを正しく設定していない場合に、招待メールに記載されたURLにアクセスできない」という問題に対応する
このようにこのチケットで扱う問題を切り替えます。具体的に何を問題として、何を修正するかについては note-9 以降を参照してください。
(追記:)設定ファイルを正しく設定していない状況は、SNS設置者のミスと見做されそうではあるが、OpenPNE側にも #1749 (OpenPNE2からのアップグレードガイドに OpenPNE.yml を作成する説明がない)のような問題があり、一概に「設定ファイルを記述し忘れていることが悪い」と言い切れるものではないことを示しておく。
現象¶
- (case1) base_url: "http://mydomain.jp/openpne" (正しい指定)
- 【OK】招待メール中のSNS参加リンク: http://mydomain.jp/openpne/member/register/token/...
- 【OK】招待メール署名にあるSNSのURL: http://mydomain.jp/openpne
- (case2) base_url: "http://mydomain.jp" ("/openpne"の欠けた指定)
- 【*NG】招待メール中のSNS参加リンク: http://mydomain.jp/member/register/token/...
- 【*NG】招待メール署名にあるSNSのURL: http://mydomain.jp
- (case3) base_url: "http://example.com"
- 【NG】招待メール中のSNS参加リンク: http://mydomain.jp//member/register/token/...
- 【*NG】招待メール署名にあるSNSのURL: http://example.com
- (case4) base_url 無指定
- 【NG】招待メール中のSNS参加リンク: http://mydomain.jp//member/register/token/...
- 【*NG】招待メール署名にあるSNSのURL: http://example.com
【*NG】と示したものは、適切なURLが出力されていませんが、問題とみなす必要はないものです。
上記について説明を示します:
- case1 は「設定ファイルを正しく記述した場合」で、適切なURLが出力されています
- case2 は「設定ファイルを不正に記述した場合」で、URLは不適切ですが、これは設定ファイルを不正に記述していることが原因であるため問題とみなす必要はありません
- case3, case4 は「設定ファイルを記述していない場合」で、招待メールのSNS参加リンクのドメインを見ると『ドメインを補完しようとしているが、サブディレクトリが抜け落ちている』という不自然な状態になっています
補足¶
サブディレクトリが抜け落ちると示していますが、厳密には「末尾のディレクトリ名が抜け落ちる」というものです。
note-9 で示されていますが、 dirname() 関数がパスの最後のディレクトリを除去してしまうという仕様に基づく問題です(dirname() の仕様が問題というよりは、当該部分で dirname() を用いていることが原因です)。
dirname('/usr/bin/ls') => '/usr/bin' dirname('/usr/bin/') => '/usr' dirname('/usr/bin') => '/usr' dirname('/etc/') => '/'
対応すべき問題¶
case3, case4 の場合に、招待メールのURL(base_url相当部分)の補完が不十分であり、不自然なURLを生成してしまっているため、これを修正する。
- 修正前の動作
- 前提:サブディレクトリ(パス)を持つようなURLでSNSにアクセスする環境で、case3, case4 の場合、
- 招待メールにおいて、SNS参加リンクのサブディレクトリ部分の末のディレクトリ名が抜け落ちる
- 修正後の動作
- 前提:サブディレクトリ(パス)を持つようなURLでSNSにアクセスする環境で、case3, case4 の場合、
- 招待メールにおいて、SNS参加リンクが適切なURL(新規登録画面に遷移できるURL)となっている
pnetan さんが約14年前に更新
- 優先度 を Normal(通常) から Urgent(急いで) に変更
http://sns.openpne.jp/communityTopic/6460 でも、似た報告が上がっています。
【 環境 】 バージョン 3.4.7 ドメイン(仮) mydomain.jp OpenPNEのURL http://mydomain.jp/openpne/ 【 症状 】 新規登録の時、get@mydomain.jpに空メールを送り、 サイトからの返信メールの中のURLは下記通り、 ドメインの後の「openpne/」が抜けていますが(PC携帯同様)、 http://mydomain.jp/opAuthMailAddress/register/token/90d07... 初期アカウントより発行された招待URLは ちゃんと「openpne/」が入っています。 http://mydomain.jp/openpne/opAuthMailAddress/register/tok... どこを弄れば、ドメインの後にちゃんと「openpne/」が着くようになるでしょうか? 宜しくお願いします。
Kousuke Ebihara さんがほぼ14年前に更新
- ステータス を New(新規) から Accepted(着手) に変更
- 担当者 を Kousuke Ebihara にセット
Kousuke Ebihara さんがほぼ14年前に更新
- ステータス を Accepted(着手) から New(新規) に変更
- 対象バージョン を削除 (
OpenPNE 3.7.0)
すぐに再現の確認ができなかったのでいったん手放します。優先度は変わりませんので再現でき次第修正に取りかかってください。
Minoru Takai さんが13年以上前に更新
- ステータス を New(新規) から Accepted(着手) に変更
- 担当者 を Minoru Takai にセット
着手します。再現性を検証します。(再現できそうになければ情報をまとめた上で、担当者を手放すかもしれません)
Naoya Tozuka さんが13年以上前に更新
調査¶
チケット #2008 との類似性に着目し、config/OpenPNE.yml の base_url の指定を変えながら招待メールを発行し、- 招待メール中のSNS参加リンク
- 招待メール末尾署名にある(SNSの)URL欄
を調べてみました。
2.についてはテンプレート中から base_url 定数そのものが引かれています。
SNSの設置場所は http://mydomain.jp/openpne/ とします。
base_url: "http://mydomain.jp/openpne" (正しい指定)¶
- 招待メール中のSNS参加リンク: http://mydomain.jp/openpne/member/register/token/16194a2957624f0ce744dadc60137f40bdb
↑OK - 招待メール署名にあるSNSのURL: http://mydomain.jp/openpne
↑OK
base_url: "http://mydomain.jp" ("/openpne"の欠けた指定)¶
- 招待メール中のSNS参加リンク: http://mydomain.jp/member/register/token/16251b5d72152d5a448c8eec13c8454a104
↑"/openpne"抜け落ち - 招待メール署名にあるSNSのURL: http://mydomain.jp
↑"/openpne"抜け落ち
このケースは単に base_url の指定が不適切であると考えられます。(実装には問題ないと思われます)
base_url: "http://example.com"¶
- 招待メール中のSNS参加リンク: http://mydomain.jp//member/register/token/160a5f500a78b7af93ae5cce748c2aea697
↑ディレクトリ名"openpne"が抜け落ちた形で補完 - 招待メール署名にあるSNSのURL: http://example.com
↑自動補完は行われない
OpenPNE3の実装では、base_url に "http://example.com" を指定しておくと絶対URLの生成時に設置場所のURLに置き換えられるようになっていますが、本件のようにサブディレクトリで稼働させた場合にパス情報が正しく補完されないようです。
base_url無指定…¶
base_urlが無指定の場合、"http://example.com" が指定されているのと同様の挙動を示します。
- 招待メール中のSNS参加リンク: http://mydomain.jp//member/register/token/15959ff33fc247ed660aaeb262a7616c0ad
↑ディレクトリ名"openpne"が抜け落ちた形で補完 ←自動補完は行われない - 招待メール署名にあるSNSのURL: http://example.com
↑自動補完は行われない
問題¶
以上の調査より、本チケットで問題とされているのは以下の事象ではないかと推察します:
base_url が無指定あるいはデフォルトの "http://example.com" が指定されているとき、サブディレクトリで稼働させた場合に正しく設置場所のURLに置き換えられるようになっていない
(ポート80以外に設置した場合の同様の問題がチケット #2008 において報告されています)
原因¶
lib/config/opApplicationConfiguration.class.php の
591: $path = dirname($options['context']['prefix']);において、dirname() 関数がパスの最後のディレクトリを除去してしまう(おそらく実装者の想定外)ためです。
cf. dirname() の仕様
dirname('/usr/bin/ls') => '/usr/bin' dirname('/usr/bin/') => '/usr' dirname('/usr/bin') => '/usr' dirname('/etc/') => '/'
この箇所において dirname() を用いないように変更したところ、サブディレクトリまで正しく補完されるようになりました。
追記¶
登録完了時に送信されるメール中のトップページURLは lib/action/opAuthAction.class.php で
'url' => $this->getController()->genUrl(array('sf_route' => 'homepage'), true),で生成されています。サブディレクトリを含むURL生成は問題ないようですが、sfPatternRouting::generate() で fixGeneratedUrl() を呼んでいるため、チケット #2008 の問題(ポート番号が無視される)は発生する可能性があります。
Naoya Tozuka さんが13年以上前に更新
- 担当者 を Minoru Takai から Naoya Tozuka に変更
スクリプト名(例えば pc_frontend_dev.php) が含まれている場合にはディレクトリ名のみを取得してくる必要があり、その目的で dirname() が用いられているものと思われるが、スクリプト名が存在しない場合には dirname() は期待されている動作をしない。この点を考慮した修正が必要と思われます。
Naoya Tozuka さんが13年以上前に更新
- ステータス を Accepted(着手) から Pending Review(レビュー待ち) に変更
- 進捗率 を 0 から 50 に変更
91ed78f7 で修正を行いました。
具体的には、base_url が "http://example.com" と定義されている場合(あるいは未定義時)にopApplicationConfiguration::getAppRouting() において、options['context']['prefix'] (pathInfoPrefix)からディレクトリ名だけ抽出したものにスクリプト名を追加していた処理を削除し、pathInfoPrefix をそのまま利用するように変更しています。
この変更により、
- SNS設置場所がサブディレクトリで、
- かつ base_url が "http://example.com" あるいは未定義
の場合に、
- 絶対URLの補完が(設置場所がサブディレクトリを含む場合も含まない場合も)正しく行われる
- スクリプト名(eg. pc_frontend_dev.php)付きでアクセスした場合にも同様に正しく(スクリプト名をそのまま含んだ形で)補完される
ことを確認済です。
以上の修正についてレビューをお願い致します。
Naoya Tozuka さんが13年以上前に更新
Masato Nagasawa さんが13年以上前に更新
- ステータス を Pending Review(レビュー待ち) から Rejected(差し戻し) に変更
$this->getAppScriptName() を削除したことによって、スクリプトファイルと環境の設定が付加されない状態となっています。
指定したアプリケーションの no_script_name が false であった場合スクリプトファイルがURLに付加し、
dev モードでアクセスした場合には "/mobile_frontend_dev.php" のように生成されるべきです。
例¶
招待メールのテンプレート中に以下のような mobile_frontend へのURL生成を追加し、
pc_frontend_dev.php 経由から招待メールを送信した場合
{% app_url_for('mobile_frontend', 'member/register?token='~token, true) %}
修正前の挙動¶
/mobile_frontend_dev.php/member/register/token/***
修正後の挙動¶
mobile_frontend を指定したはずが、dirname() を削除したことによって pc_frontend_dev.php が除去されずに残ってしまう。
/pc_frontend_dev.php/member/register/token/***
Minoru Takai さんが13年以上前に更新
- 優先度 を Urgent(急いで) から High(高め) に変更
このチケットを整理します。
このチケットが作成された当初の問題内容¶
- OpenPNE3をインストールし、設定ファイル等を正しく設定している
- 送られてくる招待メールが正しいURLではなく、招待メールから新規登録ができない
具体的な利用者からの報告内容¶
- 報告(1)
http://sns.openpne.jp/communityTopic/6423 より転記 招待メールに記載されたURLにアクセスできません。 <動作環境> OpenPNE3.6beta5 CentOS5(OpenVZの仮想環境) PHP 5.2.11 mysql Ver 14.14 招待状に記載されていたURL http://ドメイン名/member/register/token/3228758dcc32ffb79b61ee61deb73c1b1 実際に利用できた(手で書き換えた)URL http://ドメイン名/sns/web/member/registerInput/token/3228758dcc32ffb79b61ee61deb73c1b1 登録完了メールには以下の正しいURLが記載されていました。 (このURLでOpenPNEにアクセス可能) http://ドメイン名/sns/web/
- 報告(2)
http://sns.openpne.jp/communityTopic/6460 でも、似た報告が上がっています。 【 環境 】 バージョン 3.4.7 ドメイン(仮) mydomain.jp OpenPNEのURL http://mydomain.jp/openpne/ 【 症状 】 新規登録の時、get@mydomain.jpに空メールを送り、 サイトからの返信メールの中のURLは下記通り、 ドメインの後の「openpne/」が抜けていますが(PC携帯同様)、 http://mydomain.jp/opAuthMailAddress/register/token/90d07... 初期アカウントより発行された招待URLは ちゃんと「openpne/」が入っています。 http://mydomain.jp/openpne/opAuthMailAddress/register/tok... どこを弄れば、ドメインの後にちゃんと「openpne/」が着くようになるでしょうか? 宜しくお願いします。
- また、公式SNSなどで公に報告されていないかもしれませんが、私(takai)は上記2件以外にも「招待メールに、いわゆるサブディレクトリ部分が抜け落ちている」といった旨の不具合報告を受けたことがあります(つまり、この問題を訴える利用者はそれなりにいるものと思われる)。
この問題(チケット)に適用されるべき対応優先度¶
もしこの問題が、特定のバージョンのOpenPNEおよびプラグインの組み合わせで『OpenPNE3をインストールし、設定ファイル等を正しく設定している』にもかかわらず発生する(あるいは発生する恐れがあると判断される)のであれば、 http://www.openpne.jp/archives/5361/ (「OpenPNE3.6 のチケット優先度と今後のリリーススケジュールについて」)に基づいて、この問題のレベル的には Urgent 以上の優先度として対応することが妥当だと思われます。
しかしながら、本チケットの note-6, note-8, note-9 を含めた、これまでの検証結果を鑑みると、利用者が報告しているような問題は【再現しない】と判断してよいと考えます。
断言はできませんが、少なくともこれまでの検証結果から考えると、この問題は、
- 「OpenPNE3をインストールし、設定ファイル等を正しく設定して『いない』場合」に、招待メールに記載されたURLにアクセスできない(URLが想定通りに生成されない)
という問題であると結論付けられると思われます。
もしもこの問題が「設定ファイル等を正しく設定している場合」にも生じる問題であったとしても、これまでの情報だけでは検証が極めて困難であるため、更なる情報を収集する必要があります(つまり、この修正後に同様の報告があれば、その時点で新たなチケットを作成して調査すべきだと考えます)。
以上の考察を以て、本チケットの優先度を Urgent から引き下げます。
ではどの優先度に下げるべきか(特に、OpenPNE-3.6.0 リリースに含まれるべきか)という判断についてですが、利用者(SNS管理者)の設定ミスとは言え、この問題に出くわす頻度は(どのような時にこの問題が再現できるかという検証結果から)それなりにあり、設定ミスがある場合にこの問題が生じてしまうことを防止する対応には意味があると判断しています。この再現条件と修正方針は本チケット note-9 以降で示されているものを指します。
(具体的な修正内容については note-13 で差し戻しがあり、まだ修正が完了していないが)修正方針は見えており、その対応による意味は少なくないと判断しているため、OpenPNE-3.6.0 への取り込みを前提とすることを含めて優先度を High に設定します。
まとめ¶
本チケットの報告(1)および報告(2)は、「OpenPNE3をインストールし、設定ファイル等を正しく設定している」という前提であるとした上で、その報告内容の問題は【再現せず】と判断します。
その上で、「設定ファイルを正しく設定しないと、この問題が起こったように見える問題がある」ことへの対応を扱うチケットへ切り替えます。
「チケットで扱う問題の切り替え」に併せて、このチケットの優先度を Urgent から High に変更します。
Minoru Takai さんが13年以上前に更新
- 題名 を 招待メールに記載されたURLにアクセスできない から 設定ファイルを記述し忘れた場合に、招待メールに記載されたURLにアクセスできない に変更
Naoya Tozuka さんが13年以上前に更新
- ステータス を Rejected(差し戻し) から Pending Review(レビュー待ち) に変更
更新履歴 45c07909a4e1ed5d737fd11392778f13154c6303 で適用されました。
メモ¶
具体的には、パスが '.php' で終わる場合にのみ dirname() を使うように修正しています。 91ed78f と合わせると
else { - $path = dirname($options['context']['prefix']); + $path = $options['context']['prefix']; + if (preg_match('/\.php$/', $path)) + { + $path = dirname($path); + } $options['context']['prefix'] = $this->getAppScriptName($application, sfConfig::get('sf_environment'), $path, $isNoScriptName); }のような修正になります。
Rimpei Ogawa さんが13年以上前に更新
- ステータス を Pending Review(レビュー待ち) から Rejected(差し戻し) に変更
本来 base_url が設定されていない環境では、ブラウザからのリクエスト以外での実行中に正しい URL の生成ができなくなってしまうため、そのような機能が(プラグイン含めて)あれば不具合が発生している(というより仕様)と思われるため、base_url が設定されていない環境での動作をどこまで保証するかは判断が難しいところです。
例えば、 note-3 のような get
@ メールによる招待状送信では base_url が設定されていない状態で受け付けると、メール内の登録URLも example.com となります。(ただ、メール投稿を受け付ける設定をするには OpenPNE.yml の mail_domain を設定する必要があるため、その直前にある base_url の設定忘れはあまりないケースだとは思います)
base_url の設定が確実になされるような対応、あるいは、base_url の設定がなくても全機能が正常に動作するような対応ができればベストだとは思いますが、これは Enhancement として将来の開発版で考えるべき事項だと思います。
このチケットで対応している部分は元々 base_url が設定されていなくても正常に動作させるためのコードであるので、不具合として対処すべきものと認識しています。
以下、このチケットでの修正内容についてのフィードバックです。
$options['context']['prefix']
の元となっている値は sfWebRequest::getPathInfoPrefix() で生成されるものですが、この中から呼ばれている getRelativeUrlRoot() に今回変更した内容と類似のコードがあります。
public function getRelativeUrlRoot() { if (null === $this->relativeUrlRoot) { if (!isset($this->options['relative_url_root'])) { $this->relativeUrlRoot = preg_replace('#/[^/]+\.php5?$#', '', $this->getScriptName()); } else { $this->relativeUrlRoot = $this->options['relative_url_root']; } } return $this->relativeUrlRoot; }
この部分を参考にして、preg_match() を使うのであれば、代わりに preg_replace() を使ってしまった方がよいと思います。
- $path = dirname($options['context']['prefix']); + $path = preg_replace('#/[^/]+\.php5?$#', '', $options['context']['prefix']);
OpenPNEとしては opApplicationConfiguration::getAppScriptName() を見る限り、拡張子が .php5
である環境には対応していないように見えるので 5?
の部分は外しても構わないです。
Naoya Tozuka さんが13年以上前に更新
- ステータス を Rejected(差し戻し) から Pending Review(レビュー待ち) に変更
更新履歴 5547e0fa0b154a6ea66c1a5d928cb865b1851824 で適用されました。
Rimpei Ogawa さんが13年以上前に更新
- ステータス を Pending Review(レビュー待ち) から Pending Testing(テスト待ち) に変更
- 進捗率 を 50 から 70 に変更
修正確認しました。問題ないです。
Minoru Takai さんが13年以上前に更新
- ステータス を Pending Testing(テスト待ち) から Fixed(完了) に変更
- 進捗率 を 70 から 100 に変更
動作テスト¶
チケットの Description を追記しましたが、
- 修正前の動作
- 【前提】:サブディレクトリ(パス)を持つようなURLでSNSにアクセスする環境で、case3, case4 の場合、
- 【結果】:招待メールにおいて、SNS参加リンクのサブディレクトリ部分の末のディレクトリ名が抜け落ちる
- 修正後の動作
- 【前提】:サブディレクトリ(パス)を持つようなURLでSNSにアクセスする環境で、case3, case4 の場合、
- 【結果】:招待メールにおいて、SNS参加リンクが適切なURL(新規登録画面に遷移できるURL)となっている
この確認を行いました。
このようなURLでSNSにアクセスできる場合(サブディレクトリが1階層〜3階層の場合)をテストし、修正前、修正後とも上記の通りになることを確認しました。
この修正による副作用については、現時点で懸念点が明らかでないため確認すべき動作を示せませんが、
- サブディレクトリをURLに含まない環境
- サブディレクトリをURLに含む環境
- 設定ファイルが正常な場合(case1)
- 設定ファイルを記述していない場合(case3, case4)
このそれぞれにおいて、URLの生成は正常に行われていることは確認しています。ここまでの考察結果を以て、副作用なく問題点を修正できているものとし、チケットを完了とします。