r29245 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r29244‎ | r29245 | r29246 >
Date:23:43, 3 January 2008
Author:simetrical
Status:old
Tags:
Comment:
Various Userrights-related fixes:
* Adjust UserrightsForm so that it inherits from SpecialPage; nuke HTMLForm. Since this breaks backward compatibility, renamed to UserrightsPage.
* Created SpecialPage::isRestricted() and enforced use of SpecialPage::userCanExecute() instead of hardcoded checks. These can now be overridden so that more complicated restriction systems work sanely. Used them for UserrightsPage (fixes bug 12489).
* A few random comment/documentation tweaks.
Also, update Special:Version date.
Modified paths:
  • /trunk/phase3/includes/AutoLoader.php (modified) (history)
  • /trunk/phase3/includes/HTMLForm.php (deleted) (history)
  • /trunk/phase3/includes/SpecialPage.php (modified) (history)
  • /trunk/phase3/includes/SpecialUserrights.php (modified) (history)
  • /trunk/phase3/includes/SpecialVersion.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/HTMLForm.php
@@ -1,107 +0,0 @@
2 -<?php
3 -/**
4 - * This file contain a class to easily build HTML forms
5 - */
6 -
7 -/**
8 - * Class to build various forms
9 - *
10 - * @author jeluf, hashar
11 - */
12 -class HTMLForm {
13 - /** name of our form. Used as prefix for labels */
14 - var $mName, $mRequest;
15 -
16 - function HTMLForm( &$request ) {
17 - $this->mRequest = $request;
18 - }
19 -
20 - /**
21 - * @private
22 - * @param $name String: name of the fieldset.
23 - * @param $content String: HTML content to put in.
24 - * @return string HTML fieldset
25 - */
26 - function fieldset( $name, $content ) {
27 - return "<fieldset><legend>".wfMsg($this->mName.'-'.$name)."</legend>\n" .
28 - $content . "\n</fieldset>\n";
29 - }
30 -
31 - /**
32 - * @private
33 - * @param $varname String: name of the checkbox.
34 - * @param $checked Boolean: set true to check the box (default False).
35 - */
36 - function checkbox( $varname, $checked=false ) {
37 - if ( $this->mRequest->wasPosted() && !is_null( $this->mRequest->getVal( $varname ) ) ) {
38 - $checked = $this->mRequest->getCheck( $varname );
39 - }
40 - return "<div><input type='checkbox' value=\"1\" id=\"{$varname}\" name=\"wpOp{$varname}\"" .
41 - ( $checked ? ' checked="checked"' : '' ) .
42 - " /><label for=\"{$varname}\">". wfMsg( $this->mName.'-'.$varname ) .
43 - "</label></div>\n";
44 - }
45 -
46 - /**
47 - * @private
48 - * @param $varname String: name of the textbox.
49 - * @param $value String: optional value (default empty)
50 - * @param $size Integer: optional size of the textbox (default 20)
51 - */
52 - function textbox( $varname, $value='', $size=20 ) {
53 - if ( $this->mRequest->wasPosted() ) {
54 - $value = $this->mRequest->getText( $varname, $value );
55 - }
56 - $value = htmlspecialchars( $value );
57 - return "<div><label>". wfMsg( $this->mName.'-'.$varname ) .
58 - "<input type='text' name=\"{$varname}\" value=\"{$value}\" size=\"{$size}\" /></label></div>\n";
59 - }
60 -
61 - /**
62 - * @private
63 - * @param $varname String: name of the radiobox.
64 - * @param $fields Array: Various fields.
65 - */
66 - function radiobox( $varname, $fields ) {
67 - foreach ( $fields as $value => $checked ) {
68 - $s .= "<div><label><input type='radio' name=\"{$varname}\" value=\"{$value}\"" .
69 - ( $checked ? ' checked="checked"' : '' ) . " />" . wfMsg( $this->mName.'-'.$varname.'-'.$value ) .
70 - "</label></div>\n";
71 - }
72 - return $this->fieldset( $varname, $s );
73 - }
74 -
75 - /**
76 - * @private
77 - * @param $varname String: name of the textareabox.
78 - * @param $value String: optional value (default empty)
79 - * @param $size Integer: optional size of the textarea (default 20)
80 - */
81 - function textareabox ( $varname, $value='', $size=20 ) {
82 - if ( $this->mRequest->wasPosted() ) {
83 - $value = $this->mRequest->getText( $varname, $value );
84 - }
85 - $value = htmlspecialchars( $value );
86 - return '<div><label>'.wfMsg( $this->mName.'-'.$varname ).
87 - "<textarea name=\"{$varname}\" rows=\"5\" cols=\"{$size}\">$value</textarea></label></div>\n";
88 - }
89 -
90 - /**
91 - * @private
92 - * @param $varname String: name of the arraybox.
93 - * @param $size Integer: Optional size of the textarea (default 20)
94 - */
95 - function arraybox( $varname , $size=20 ) {
96 - $s = '';
97 - if ( $this->mRequest->wasPosted() ) {
98 - $arr = $this->mRequest->getArray( $varname );
99 - if ( is_array( $arr ) ) {
100 - foreach ( $_POST[$varname] as $element ) {
101 - $s .= htmlspecialchars( $element )."\n";
102 - }
103 - }
104 - }
105 - return "<div><label>".wfMsg( $this->mName.'-'.$varname ).
106 - "<textarea name=\"{$varname}\" rows=\"5\" cols=\"{$size}\">{$s}</textarea>\n";
107 - }
108 -} // end class
Index: trunk/phase3/includes/SpecialUserrights.php
@@ -4,37 +4,26 @@
55 * Special page to allow managing user group membership
66 *
77 * @addtogroup SpecialPage
8 - * @todo This code is disgusting and needs a total rewrite
 8+ * @todo Use checkboxes or something, this list thing is incomprehensible to
 9+ * normal human beings.
910 */
1011
11 -/** */
12 -require_once( dirname(__FILE__) . '/HTMLForm.php');
13 -
14 -/** Entry point */
15 -function wfSpecialUserrights() {
16 - global $wgRequest;
17 - $form = new UserrightsForm($wgRequest);
18 - $form->execute();
19 -}
20 -
2112 /**
2213 * A class to manage user levels rights.
2314 * @addtogroup SpecialPage
2415 */
25 -class UserrightsForm extends HTMLForm {
26 - var $mPosted, $mRequest, $mSaveprefs;
27 - /** Escaped local url name*/
28 - var $action;
 16+class UserrightsPage extends SpecialPage {
 17+ public function __construct() {
 18+ parent::__construct( 'Userrights' );
 19+ }
2920
30 - /** Constructor*/
31 - public function __construct( &$request ) {
32 - $this->mPosted = $request->wasPosted();
33 - $this->mRequest =& $request;
34 - $this->mName = 'userrights';
35 - $this->mReason = $request->getText( 'user-reason' );
 21+ public function isRestricted() {
 22+ return true;
 23+ }
3624
37 - $titleObj = SpecialPage::getTitleFor( 'Userrights' );
38 - $this->action = $titleObj->escapeLocalURL();
 25+ public function userCanExecute( $user ) {
 26+ $available = $this->changeableGroups();
 27+ return !empty( $available['add'] ) or !empty( $available['remove'] );
3928 }
4029
4130 /**
@@ -44,41 +33,43 @@
4534 function execute() {
4635 // If the visitor doesn't have permissions to assign or remove
4736 // any groups, it's a bit silly to give them the user search prompt.
48 - $available = $this->changeableGroups();
49 - if( empty( $available['add'] ) && empty( $available['remove'] ) ) {
 37+ global $wgUser;
 38+ if( !$this->userCanExecute( $wgUser ) ) {
5039 // fixme... there may be intermediate groups we can mention.
51 - global $wgOut, $wgUser;
 40+ global $wgOut;
5241 $wgOut->showPermissionsErrorPage( array(
5342 $wgUser->isAnon()
5443 ? 'userrights-nologin'
5544 : 'userrights-notallowed' ) );
5645 return;
5746 }
58 -
 47+
 48+ $this->setHeaders();
 49+
5950 // show the general form
6051 $this->switchForm();
61 - if( $this->mPosted ) {
 52+
 53+ global $wgRequest;
 54+ if( $wgRequest->wasPosted() ) {
6255 // show some more forms
63 - if( $this->mRequest->getCheck( 'ssearchuser' ) ) {
64 - $this->editUserGroupsForm( $this->mRequest->getVal( 'user-editname' ) );
 56+ if( $wgRequest->getCheck( 'ssearchuser' ) ) {
 57+ $this->editUserGroupsForm( $wgRequest->getVal( 'user-editname' ) );
6558 }
6659
6760 // save settings
68 - if( $this->mRequest->getCheck( 'saveusergroups' ) ) {
69 - global $wgUser;
70 - $username = $this->mRequest->getVal( 'user-editname' );
71 - $reason = $this->mRequest->getVal( 'user-reason' );
72 - if( $wgUser->matchEditToken( $this->mRequest->getVal( 'wpEditToken' ), $username ) ) {
 61+ if( $wgRequest->getCheck( 'saveusergroups' ) ) {
 62+ $username = $wgRequest->getVal( 'user-editname' );
 63+ $reason = $wgRequest->getVal( 'user-reason' );
 64+ if( $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ), $username ) ) {
7365 $this->saveUserGroups( $username,
74 - $this->mRequest->getArray( 'removable' ),
75 - $this->mRequest->getArray( 'available' ),
 66+ $wgRequest->getArray( 'removable' ),
 67+ $wgRequest->getArray( 'available' ),
7668 $reason );
7769 }
7870 }
7971 }
8072 }
8173
82 -
8374 /**
8475 * Save user groups changes in the database.
8576 * Data comes from the editUserGroupsForm() form function
@@ -87,7 +78,7 @@
8879 * @param array $removegroup id of groups to be removed.
8980 * @param array $addgroup id of groups to be added.
9081 * @param string $reason Reason for group change
91 - *
 82+ * @return null
9283 */
9384 function saveUserGroups( $username, $removegroup, $addgroup, $reason = '') {
9485 $user = $this->fetchUser( $username );
@@ -130,12 +121,16 @@
131122 }
132123
133124 $log = new LogPage( 'rights' );
 125+
 126+ global $wgRequest;
134127 $log->addEntry( 'rights',
135128 $user->getUserPage(),
136 - $this->mReason,
 129+ $wgRequest->getText( 'user-reason' ),
137130 array(
138131 $this->makeGroupNameList( $oldGroups ),
139 - $this->makeGroupNameList( $newGroups ) ) );
 132+ $this->makeGroupNameList( $newGroups )
 133+ )
 134+ );
140135 }
141136
142137 /**
@@ -154,9 +149,8 @@
155150
156151 $this->showEditUserGroupsForm( $user, $groups );
157152
158 - // This isn't really ideal logging behavior,
159 - // but let's not hide the interwiki logs if
160 - // we're using them as is.
 153+ // This isn't really ideal logging behavior, but let's not hide the
 154+ // interwiki logs if we're using them as is.
161155 $this->showLogFragment( $user, $wgOut );
162156 }
163157
@@ -233,7 +227,7 @@
234228 function switchForm() {
235229 global $wgOut, $wgRequest;
236230 $username = $wgRequest->getText( 'user-editname' );
237 - $form = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->action, 'name' => 'uluser' ) );
 231+ $form = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getTitle()->escapeLocalURL(), 'name' => 'uluser' ) );
238232 $form .= '<fieldset><legend>' . wfMsgHtml( 'userrights-lookup-user' ) . '</legend>';
239233 $form .= '<p>' . Xml::inputLabel( wfMsg( 'userrights-user-editname' ), 'user-editname', 'username', 30, $username ) . '</p>';
240234 $form .= '<p>' . Xml::submitButton( wfMsg( 'editusergroup' ), array( 'name' => 'ssearchuser' ) ) . '</p>';
@@ -279,7 +273,7 @@
280274 $grouplist = '<p>' . wfMsgHtml( 'userrights-groupsmember' ) . ' ' . implode( ', ', $list ) . '</p>';
281275 }
282276 $wgOut->addHTML(
283 - Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->action, 'name' => 'editGroup' ) ) .
 277+ Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getTitle()->escapeLocalURL(), 'name' => 'editGroup' ) ) .
284278 Xml::hidden( 'user-editname', $user->getName() ) .
285279 Xml::hidden( 'wpEditToken', $wgUser->editToken( $user->getName() ) ) .
286280 Xml::openElement( 'fieldset' ) .
Index: trunk/phase3/includes/AutoLoader.php
@@ -93,7 +93,6 @@
9494 'FileStore' => 'includes/FileStore.php',
9595 'FSException' => 'includes/FileStore.php',
9696 'FSTransaction' => 'includes/FileStore.php',
97 - 'HTMLForm' => 'includes/HTMLForm.php',
9897 'HistoryBlob' => 'includes/HistoryBlob.php',
9998 'ConcatenatedGzipHistoryBlob' => 'includes/HistoryBlob.php',
10099 'HistoryBlobStub' => 'includes/HistoryBlob.php',
@@ -232,7 +231,7 @@
233232 'UploadForm' => 'includes/SpecialUpload.php',
234233 'UploadFormMogile' => 'includes/SpecialUploadMogile.php',
235234 'LoginForm' => 'includes/SpecialUserlogin.php',
236 - 'UserrightsForm' => 'includes/SpecialUserrights.php',
 235+ 'UserrightsPage' => 'includes/SpecialUserrights.php',
237236 'SpecialVersion' => 'includes/SpecialVersion.php',
238237 'WantedCategoriesPage' => 'includes/SpecialWantedcategories.php',
239238 'WantedPagesPage' => 'includes/SpecialWantedpages.php',
Index: trunk/phase3/includes/SpecialPage.php
@@ -112,7 +112,7 @@
113113 'Ancientpages' => array( 'SpecialPage', 'Ancientpages' ),
114114 'Deadendpages' => array( 'SpecialPage', 'Deadendpages' ),
115115 'Protectedpages' => array( 'SpecialPage', 'Protectedpages' ),
116 - 'Protectedtitles' => array( 'SpecialPage', 'Protectedtitles' ),
 116+ 'Protectedtitles' => array( 'SpecialPage', 'Protectedtitles' ),
117117 'Allpages' => array( 'IncludableSpecialPage', 'Allpages' ),
118118 'Prefixindex' => array( 'IncludableSpecialPage', 'Prefixindex' ) ,
119119 'Ipblocklist' => array( 'SpecialPage', 'Ipblocklist' ),
@@ -135,7 +135,7 @@
136136 'Import' => array( 'SpecialPage', 'Import', 'import' ),
137137 'Lockdb' => array( 'SpecialPage', 'Lockdb', 'siteadmin' ),
138138 'Unlockdb' => array( 'SpecialPage', 'Unlockdb', 'siteadmin' ),
139 - 'Userrights' => array( 'SpecialPage', 'Userrights' ),
 139+ 'Userrights' => 'UserrightsPage',
140140 'MIMEsearch' => array( 'SpecialPage', 'MIMEsearch' ),
141141 'Unwatchedpages' => array( 'SpecialPage', 'Unwatchedpages', 'unwatchedpages' ),
142142 'Listredirects' => array( 'SpecialPage', 'Listredirects' ),
@@ -352,7 +352,7 @@
353353
354354 foreach ( self::$mList as $name => $rec ) {
355355 $page = self::getPage( $name );
356 - if ( $page->isListed() && $page->getRestriction() == '' ) {
 356+ if ( $page->isListed() && !$page->isRestricted() ) {
357357 $pages[$name] = $page;
358358 }
359359 }
@@ -373,11 +373,12 @@
374374
375375 foreach ( self::$mList as $name => $rec ) {
376376 $page = self::getPage( $name );
377 - if ( $page->isListed() ) {
378 - $restriction = $page->getRestriction();
379 - if ( $restriction != '' && $wgUser->isAllowed( $restriction ) ) {
380 - $pages[$name] = $page;
381 - }
 377+ if (
 378+ $page->isListed()
 379+ and $page->isRestricted()
 380+ and $page->userCanExecute( $wgUser )
 381+ ) {
 382+ $pages[$name] = $page;
382383 }
383384 }
384385 return $pages;
@@ -611,10 +612,25 @@
612613 }
613614
614615 /**
 616+ * Can be overridden by subclasses with more complicated permissions
 617+ * schemes.
 618+ *
 619+ * @return bool Should the page be displayed with the restricted-access
 620+ * pages?
 621+ */
 622+ public function isRestricted() {
 623+ return $this->mRestriction != '';
 624+ }
 625+
 626+ /**
615627 * Checks if the given user (identified by an object) can execute this
616 - * special page (as defined by $mRestriction)
 628+ * special page (as defined by $mRestriction). Can be overridden by sub-
 629+ * classes with more complicated permissions schemes.
 630+ *
 631+ * @param User $user The user to check
 632+ * @return bool Does the user have permission to view the page?
617633 */
618 - function userCanExecute( &$user ) {
 634+ public function userCanExecute( &$user ) {
619635 return $user->isAllowed( $this->mRestriction );
620636 }
621637
Index: trunk/phase3/includes/SpecialVersion.php
@@ -52,7 +52,7 @@
5353 $ret =
5454 "__NOTOC__
5555 This wiki is powered by '''[http://www.mediawiki.org/ MediaWiki]''',
56 - copyright (C) 2001-2007 Magnus Manske, Brion Vibber, Lee Daniel Crocker,
 56+ copyright (C) 2001-2008 Magnus Manske, Brion Vibber, Lee Daniel Crocker,
5757 Tim Starling, Erik Möller, Gabriel Wicke, Ævar Arnfjörð Bjarmason,
5858 Niklas Laxström, Domas Mituzas, Rob Church and others.
5959

Follow-up revisions

RevisionCommit summaryAuthorDate
r29246r29245 fixed bug 12489 -- add release note linebrion23:54, 3 January 2008

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r29235(bug 12489) Special:Userrights should be listed under restricted special pageshuji21:07, 3 January 2008

Status & tagging log