$cantedit 関係のまとめ

  • 元タイトル: unfreezeが$canteditを確認せずにedit_formを出している。
  • ページ: BugTrack2
  • 投稿者: g@kko
  • 優先順位: 普通
  • 状態: 着手
  • カテゴリー: 本体バグ
  • 投稿日: 2007-06-29 (金) 13:11:13
  • バージョン: unfreeze.inc.php,v 1.10


修正

「システム側が自動的に更新するページ」を保護するための設定 $cantedit (RecentChanges、RecentDeleted などが該当する) に関するコードを集約し、想定されている挙動にそった動作に改める。

  • cvs:lib/func.php (1.92)
    • is_cantedit() を追加。あちこちに散らばっていた $canteditの処理を集約。ついでにhashを使用
    • is_editable(): 早速 is_cantedit()を使用
  • $cantedit はユーザーが編集できない
    • cvs:lib/html.php (1.64)
      • 編集対象ではないので、($whatsnewの場合と同様に)編集のためのUIを表示しない。
      • 一般ユーザーが作成した既存のコンテンツではないので、一般ユーザー向けテンプレートの対象にもならない
    • cvs:lib/link.php (1.15) -- $cantedit を対象にしない
    • 編集対象ではないので、凍結の対象でもない
    • cvs:plugin/rename.inc.php (1.35) -- rename元にも、rename先にもならない*1

メッセージ

unfreeze.inc.php,v 1.10および1.11(CVS)において、PLUGIN_UNFREEZE_EDITを有効にしている場合、凍結解除後に編集フォームを表示していますが、編集可能かどうかのチェックをしていないようです。

これにより

$whatsnew     = 'RecentChanges'; // Modified page list
$whatsdeleted = 'RecentDeleted'; // Removeed page list

の編集フォームが表示されます。(編集結果は保存できません)

そもそもの仕様は?

  • そもそも$canteditで指定したページは凍結/凍結解除対象なのか。編集を許可しないので、凍結も対象外と思われます。
    • 対象外ということであれば、以下2項の対応が必要と思われます。
      • $canteditで指定したページはskinで凍結/凍結解除を表示しない
      • freeze/unfreezeプラグインで$canteditを処理対象外とする
    • 対象ということであれば、以下1項の対応が必要と思われます。
      • $canteditで指定したページを凍結解除した場合、edit_formを表示しない。

修正案

  • 引数のページ名が$canteditかどうか判定する関数をlib/func.phpに追加 lib/func.php (1.92)にて修正
  • 分類1:$whatsnewから$canteditに条件を変えるもの
  • 分類2-1:明らかに例外処理の漏れ
    • freeze.inc.php plugin/freeze.inc.php (1.10)にて修正
    • unfreeze.inc.php plugin/unfreeze.inc.php (1.12)にて修正
    • attach.inc.php -- 関連:BugTrack2/261 凍結ページでのattachの画面遷移
    • rename.inc.php -- $whatsnewは例外処理を行っている。凍結していてもリネーム可能。$whatsnew以外の$cantedit指定ページをリネームすると、$canteditの指定を外れる場合がある。 plugin/rename.inc.php (1.35)にて修正
  • 分類2-2:仕様上、例外処理を追加すべきか判断が必要なもの
    • diff.inc.php -- デフォルトの$canteditのページは差分は作成されないため不要?
    • backup.inc.php -- デフォルトの$canteditのページはバックアップは作成されないため不要?
    • template.inc.php -- 凍結していても複製は可能。では、$canteditは?
      • ページの編集で「雛形とするページ」で$whatsnewは表示しないよう制御しているが、templateでは制御していない。 lib/html.php (1.64) で修正
      • ページの編集で「雛形とするページ」と同様に$canteditは複製の対象外とする。
    • source.inc.php -- 凍結していてもソースの表示は可能。では、$canteditは?
  • 分類3:対策が必要ないもの。
    • edit.inc.php -- check_editable(is_editable)を行っている。
    • add.inc.php -- check_editable(is_editable)を行っている。
  • 分類4:ページを更新するプラグインの対策

func.php/is_cantedit

  • 2007-07-25 (水) 07:18:15
    func.php,v 1.91
    line 47-
     // If the page exists
     function is_page($page, $clearcache = FALSE)
     {
     	if ($clearcache) clearstatcache();
     	return file_exists(get_filename($page));
     }
    +
    +function is_cantedit($page)
    +{
    +	global $cantedit;
    +	static $is_cantedit;
    +	if (! isset($is_cantedit)) {
    +		foreach($cantedit as $key) {
    +			$is_cantedit[$key] = TRUE;
    +		}
    +	}
    +	return isset($is_cantedit[$page]);
    +}
     
     function is_editable($page)
     {
    -	global $cantedit;
     	static $is_editable = array();
     
     	if (! isset($is_editable[$page])) {
     		$is_editable[$page] = (
     			is_pagename($page) &&
     			! is_freeze($page) &&
    -			! in_array($page, $cantedit)
    +			! is_cantedit($page)
     		);
     	}
     
     	return $is_editable[$page];
     }

skinの修正案(分類1)

  • 2007-07-25 (水) 07:18:15
    html.php,v 1.63
    line 12-
      function catbody($title, $page, $body)
     {
     	global $script, $vars, $arg, $defaultpage, $whatsnew, $help_page, $hr;
    -	global $attach_link, $related_link, $cantedit, $function_freeze;
    +	global $attach_link, $related_link, $function_freeze;
  • 2007-07-20 (金) 12:58:30
  • 2007-07-25 (水) 07:18:15
    html.php,v 1.57 line 91-
    html.php,v 1.63 line 84-
    	// Init flags
    -	$is_page = (is_pagename($_page) && ! arg_check('backup') && $_page != $whatsnew);
    +	$is_page = (is_pagename($_page) && ! arg_check('backup') && ! is_cantedit($_page));
    	$is_read = (arg_check('read') && is_page($_page));
    	$is_freeze = is_freeze($_page);
    リロードも非表示となりますが、skinについては上記の対応で問題ないと思います。
    なお、初期設定で$whatsnewは$canteditに包含されています。

freeze.inc.phpの修正案(分類2-1) 

  • 2007-07-21 (土) 14:41:12
  • 2007-07-25 (水) 07:18:15
    freeze.inc.php,v 1.9 line 10-
    function plugin_freeze_action()
    {
    -	global $script, $vars, $function_freeze;
    +	global $script, $vars, $function_freeze, $cantedit;
    	global $_title_isfreezed, $_title_freezed, $_title_freeze;
    	global $_msg_invalidpass, $_msg_freezing, $_btn_freeze;
    
    	$page = isset($vars['page']) ? $vars['page'] : '';
    -	if (! $function_freeze || ! is_page($page));
    +	if (! $function_freeze || ! is_page($page) || is_cantedit($page));
    		return array('msg' => '', 'body' => '');

unfreeze.inc.phpの修正案(分類2-1) 

  • 2007-07-21 (土) 14:47:18
  • 2007-07-25 (水) 07:18:15
    unfreeze.inc.php,v 1.10 line 10-
    unfreeze.inc.php,v 1.11 line 12-
    function plugin_unfreeze_action()
    {
    -	global $script, $vars, $function_freeze;
    +	global $script, $vars, $function_freeze, $cantedit;
    	global $_title_isunfreezed, $_title_unfreezed, $_title_unfreeze;
    	global $_msg_invalidpass, $_msg_unfreezing, $_btn_unfreeze;
    
    	$page = isset($vars['page']) ? $vars['page'] : '';
    -	if (! $function_freeze || ! is_page($page));
    +	if (! $function_freeze || ! is_page($page) || is_cantedit($page));
    		return array('msg' => '', 'body' => '');

rename.inc.phpの修正案(分類2-1)

  • 2007-07-25 (水) 07:18:15
    rename.inc.php,v 1.34
    line 13-
     function plugin_rename_action()
     {
    -	global $whatsnew;
    -
     	if (PKWK_READONLY) die_message('PKWK_READONLY prohibits this');
     
     
    line 46-
     		} else if (! is_page($refer)) {
     			return plugin_rename_phase1('notpage', $refer);
     
    -		} else if ($refer === $whatsnew) {
    +		} else if (is_cantedit($refer)) {
    			return plugin_rename_phase1('norename', $refer);
    
    		} else if ($page === '' || $page === $refer) {
    			return plugin_rename_phase2();
    
    line 405-
     function plugin_rename_getselecttag($page)
     {
    -	global $whatsnew;
    -
    	$pages = array();
    	foreach (get_existpages() as $_page) {
    -		if ($_page === $whatsnew) continue;
    +		if (is_cantedit($_page)) continue;
    
     		$selected = ($_page === $page) ? ' selected' : '';

article.inc.phpの修正案(分類4)

  • 2007-07-25 (水) 07:18:15
    article.inc.php,v 1.25
    line 46-
     function plugin_article_action()
     {
     	global $script, $post, $vars, $cols, $rows, $now;
     	global $_title_collided, $_msg_collided, $_title_updated;
     	global $_plugin_article_mailto, $_no_subject, $_no_name;
     	global $_msg_article_mail_sender, $_msg_article_mail_page;
     
     	if (PKWK_READONLY) die_message('PKWK_READONLY prohibits editing');
     
    -	if ($post['msg'] == '')
    +	if ($post['msg'] == '' || is_cantedit($post['refer']))
     		return array('msg'=>'','body'=>'');
     
     
    line 143-
     function plugin_article_convert()
     {
     	global $script, $vars, $digest;
     	global $_btn_article, $_btn_name, $_btn_subject;
     	static $numbers = array();
     
    -	if (PKWK_READONLY) return ''; // Show nothing
    +	if (PKWK_READONLY || is_cantedit($vars['page'])) return ''; // Show nothing

comment.inc.phpの修正案(分類4)

  • 2007-07-25 (水) 07:18:15
    comment.inc.php,v 1.36
    line 21-
     function plugin_comment_action()
     {
     	global $script, $vars, $now, $_title_updated, $_no_name;
     	global $_msg_comment_collided, $_title_comment_collided;
     
     	if (PKWK_READONLY) die_message('PKWK_READONLY prohibits editing');
     
    -	if (! isset($vars['msg'])) return array('msg'=>'', 'body'=>''); // Do nothing
    +	if ($post['msg'] == '' || is_cantedit($post['refer']))
    +		return array('msg'=>'','body'=>''); // Do nothing
     
     
    line 87-
     function plugin_comment_convert()
     {
     	global $vars, $digest, $_btn_comment, $_btn_name, $_msg_comment;
     	static $numbers = array();
     	static $comment_cols = PLUGIN_COMMENT_SIZE_MSG;
     
    -	if (PKWK_READONLY) return ''; // Show nothing
    +	if (PKWK_READONLY || is_cantedit($vars['page'])) return ''; // Show nothing

template.inc.php(分類2-2)

template.inc.php,v 1.21
line 8-
 function plugin_template_action()
 {
	global $script, $vars;
	global $_title_edit;
	global $_msg_template_start, $_msg_template_end, $_msg_template_page, $_msg_template_refer;
	global $_btn_template_create, $_title_template;
	global $_err_template_already, $_err_template_invalid, $_msg_template_force;
	if (PKWK_READONLY) die_message('PKWK_READONLY prohibits editing');
-	if (! isset($vars['refer']) || ! is_page($vars['refer']))
+	if (! isset($vars['refer']) || ! is_page($vars['refer']) || is_cantedit($vars['refer']))
		return FALSE;

コメント

  • BugTrack2/197#vdcc78fd の一部に関連するコメントが -- 2007-07-01 (日) 13:05:18
  • 中略(過去のコメントに移動しました*2
  • 各種まとめありがとうございます。$canteditはどちらかといえば古くて原始的な機構に分類されるかと思いますが、意図を汲み取って考えるに「絶対に編集を許さないセキュリティレイヤー」を実現していないとつじつまが合わないでしょう。その意味でfreezeの対象外でなければならないと思います。 -- henoheno 2007-07-19 (木) 22:41:06
  • 「絶対に編集を許さないセキュリティレイヤー」という思想で考えると、デフォルトskinの対応はnavigatorとtoolbarの修正で、以下が対象になると思います。
navigatorで非表示にするもの
編集,凍結/凍結解除,差分,バックアップ,添付
toolbarで非表示にするもの
編集,凍結/凍結解除,差分,バックアップ,添付,複製,名前変更
  • freeze/unfreeze以外にedit,diff,backup,attach,template,renameの各プラグインについても考慮が必要かどうか、調査・検討が必要ですね。 -- g@kko 2007-07-20 (金) 07:26:02
  • ざっと関連するプラグインのソースを見ました。以下の方針で修正案を提示する予定です。 -- g@kko 2007-07-21 (土) 14:28:14
    • 分類1:$whatsnewを判定して例外処理を行っているものについては、$canteditを判定対象に変更する。
    • 分類2:$whatsnew及び$canteditどちらに対しても例外処理を行っていないものについては、
      • 分類2-1:明らかに例外処理が漏れているものは、処理を追加する。
      • 分類2-2:例外処理が必要かどうか、仕様上ビミョウなもので、PukiWiki Developers Teamの判断を仰ぐもの。
    • 分類3:対策が必要でないもの。
  • ページ名を引数とするアクションプラグインのadd ,sourceについても考慮が必要かどうか、調査・検討を行います。なお、tbについては検討対象外とします。 -- g@kko 2007-07-21 (土) 15:07:33
  • お疲れ様です。$canteditを操作するためのコードがあちこちに発散してしまわないよう、仮に関数に集約させておくのが良いかと思います。例えばこんなの -- henoheno 2007-07-22 (日) 14:34:05
    function is_cantedit($page)
    {
    	global $cantedit;
    	static $hash;
    	if (! isset($hash)) {
    		foreach($cantedit as $part) {
    			$hash[$part] = TRUE;
    		}
    	}
    	return isset($hash[$page]);
    }
  • コードの集約(関数化)までは気がまわりませんでした。勉強になります。関数はlib/func.phpに追加、lib/func.php/function is_editableにも手を入れるカタチで修正案を後日、提示させていただきます。 -- g@kko 2007-07-23 (月) 08:38:51
  • 悩ましき諸問題の追加です。$canteditで指定したページにarticle,comment,insert,memo,voteがある場合、現状、更新可能です。こちらも考慮が必要と思われます。 -- g@kko 2007-07-23 (月) 08:49:50
    • article,comment,insert,memo,voteについては、凍結ページにおいても更新可能です。これらを編集不可とする辺りが凍結とcanteditとの違いになるのかな・・・ -- g@kko 2007-07-23 (月) 12:54:19
  • rename.inc.phpを分類2-2から分類2-1へ移動しました。 -- $whatsnewは例外処理を行っているため -- g@kko 2007-07-24 (火) 07:31:55
  • 分類4を追加しました。--ページを更新するプラグインの対策を分類します。対策として、PKWK_READONLY相当の処理かなと思いました。 -- g@kko 2007-07-25 (水) 07:18:15
    • paint.inc.phpを分類4に追加しました。 -- g@kko 2007-07-26 (木) 07:22:36
  • 各種ありがとうございます。仮の関数 is_cantedit() ですが、名前を例えば cantedit() にして、出力する結果を反転 ( ! is_cantedit() == cantedit() ) させた方が、コードが簡潔になるでしょうか? (お任せします)-- henoheno 2007-07-26 (木) 10:13:54
    • 個別のプラグインをケアすべきかどうかは数と種類が多い分(もう見られているようですが)簡単な事ではないので、$cantedit を扱うコードを集約する、といった部分から段階的に取り込みます。 -- henoheno 2007-07-26 (木) 10:15:26
  • $cantedit の実装がシンプルすぎる*3という点、またページの改変手段(wiki/*.txtへアクセスする手法)がプラグインごとにバラバラである点から、「各pluginをhackしまくらねばならない」かのような強迫観念を受けてしまいそうですね。 -- henoheno 2007-07-26 (木) 10:38:44
    • その路線は目先の負担感が大きくて健康的ではないので、とりあえずここでは考えないでおいて、$canteditが期待する「編集禁止を強制する」点を少ないコストで実現(表現)したいのなら、page_write() のような関数にis_cantedit()のようなものを仕込む、なんて所を取り組んだほうが楽ではないかと思いましたがどうでしょうか。※各プラグインの様子を見て、掘り起こして行く事にも価値はあるので、無駄ではないと思います。各プラグインのファイル処理は本当にバラバラなのですが、抽象化の作業は別件ですね -- henoheno 2007-07-26 (木) 10:41:57
    • 「絶対に編集を許さない」の実装が簡単でないことを痛感しております。勉強も兼ねて各プラグインのソースを見て、仰るとおり、「本当にバラバラ」で、違いの意味を追いかけたりしていました。また、バラバラなものに対して、一貫した修正案をどう提案してよいものやら悩んでおりました。7/26にいただいたコメントを含め、今しばらくお時間をください。 -- g@kko 2007-07-27 (金) 12:43:43
  • だいたい固まっているところ + αをコミットしました。 $cantedit の中に一般コンテンツが来るはずはない、という観点から、 plugin_*_convert に関する処理はとりあえず無視しています。 -- henoheno 2007-07-28 (土) 23:30:39
    • すいません。多忙でなかなか時間が取れません。コミットの内容も確認できていません。plugin_*_convertの無視については問題ないと思います。もともとそういう使い方*4をすることに矛盾がありますんで。 -- g@kko 2007-08-03 (金) 16:14:41
    • 修正内容、cvsの内容を確認しました。たいへんお疲れさまでした。とてもスジが通っている修正だと思います。私が思っていた以上の範囲で修正されていて、感銘を受けました。 -- g@kko 2007-08-06 (月) 12:47:06
  • 残件について -- g@kko 2007-08-07 (火) 06:46:29
    • lib/html.php (1.64)の修正で、一般ユーザー向けテンプレートの対象にしないよう変更したので、template.inc.phpについても「雛形とするページ」とならないよう修正する
  • diff, backup, sourceについては、判断に悩みますが、現状のままでも大きな影響はないという整理でよいかと思います。diff,backupは対象がないため、機能の意図する表示がなく、sourceは表示しても問題ないという判断です。
  • page_write() のような関数にis_cantedit()のようなものを仕込む検討
  • plugin_*_actionの対応に関するものの整理
  • 他にはattach.inc.phpを整理したいと思っています。本件BugTrack2/255ではなく、BugTrack2/261がメインの提案になると思っています。

*1 今renameの整理中だが、整理すればもう一つパスがつぶせるかもしれない
*2 局所的な回避策ではなく、仕様を再確認し実装するため、一旦、unfreezeの対策は別ページに移動させていただきました。
*3 今まで注目されていなかったので仕方ないけれど、従来のロジックが関数化されていない(構造化プログラミングの初期段階)。また設定の記法が実はhash等のテクニックを使っておらず、内部でそれをそのまま使っていたので、ユーザーには解り易いが性能が良くなく、バランスが悪かった
*4 canteditなページに更新系プラグインを使うこと

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2009-04-04 (土) 04:39:33
Site admin: PukiWiki Development Team

PukiWiki 1.5.2+ © 2001-2019 PukiWiki Development Team. Powered by PHP 5.6.40-0+deb8u7. HTML convert time: 0.387 sec.

OSDN