Index: trunk/phase3/includes/OutputPage.php |
— | — | @@ -124,9 +124,12 @@ |
125 | 125 | |
126 | 126 | var $mTemplateIds = array(); |
127 | 127 | |
128 | | - /** Initialized with a global value. Let us override it. |
129 | | - * Should probably get deleted / rewritten ... */ |
130 | | - var $mAllowUserJs; |
| 128 | + # What level of 'untrustworthiness' is allowed in CSS/JS modules loaded on this page? |
| 129 | + # @see ResourceLoaderModule::$origin |
| 130 | + # ResourceLoaderModule::ORIGIN_ALL is assumed unless overridden; |
| 131 | + protected $mAllowedModules = array( |
| 132 | + ResourceLoaderModule::TYPE_COMBINED => ResourceLoaderModule::ORIGIN_ALL, |
| 133 | + ); |
131 | 134 | |
132 | 135 | /** |
133 | 136 | * @EasterEgg I just love the name for this self documenting variable. |
— | — | @@ -212,15 +215,6 @@ |
213 | 216 | ); |
214 | 217 | |
215 | 218 | /** |
216 | | - * Constructor |
217 | | - * Initialise private variables |
218 | | - */ |
219 | | - function __construct() { |
220 | | - global $wgAllowUserJs; |
221 | | - $this->mAllowUserJs = $wgAllowUserJs; |
222 | | - } |
223 | | - |
224 | | - /** |
225 | 219 | * Redirect to $url rather than displaying the normal page |
226 | 220 | * |
227 | 221 | * @param $url String: URL |
— | — | @@ -367,12 +361,33 @@ |
368 | 362 | } |
369 | 363 | |
370 | 364 | /** |
| 365 | + * Filter an array of modules to remove insufficiently trustworthy members |
| 366 | + * @param $modules Array |
| 367 | + * @return Array |
| 368 | + */ |
| 369 | + protected function filterModules( $modules, $type = ResourceLoaderModule::TYPE_COMBINED ){ |
| 370 | + $resourceLoader = $this->getResourceLoader(); |
| 371 | + $filteredModules = array(); |
| 372 | + foreach( $modules as $val ){ |
| 373 | + $module = $resourceLoader->getModule( $val ); |
| 374 | + if( $module->getOrigin() <= $this->getAllowedModules( $type ) ) { |
| 375 | + $filteredModules[] = $val; |
| 376 | + } |
| 377 | + } |
| 378 | + return $filteredModules; |
| 379 | + } |
| 380 | + |
| 381 | + /** |
371 | 382 | * Get the list of modules to include on this page |
372 | 383 | * |
| 384 | + * @param $filter Bool whether to filter out insufficiently trustworthy modules |
373 | 385 | * @return Array of module names |
374 | 386 | */ |
375 | | - public function getModules() { |
376 | | - return array_values( array_unique( $this->mModules ) ); |
| 387 | + public function getModules( $filter = false, $param = 'mModules' ) { |
| 388 | + $modules = array_values( array_unique( $this->$param ) ); |
| 389 | + return $filter |
| 390 | + ? $this->filterModules( $modules ) |
| 391 | + : $modules; |
377 | 392 | } |
378 | 393 | |
379 | 394 | /** |
— | — | @@ -390,8 +405,8 @@ |
391 | 406 | * Get the list of module JS to include on this page |
392 | 407 | * @return array of module names |
393 | 408 | */ |
394 | | - public function getModuleScripts() { |
395 | | - return array_values( array_unique( $this->mModuleScripts ) ); |
| 409 | + public function getModuleScripts( $filter = false ) { |
| 410 | + return $this->getModules( $filter, 'mModuleScripts' ); |
396 | 411 | } |
397 | 412 | |
398 | 413 | /** |
— | — | @@ -410,8 +425,8 @@ |
411 | 426 | * |
412 | 427 | * @return Array of module names |
413 | 428 | */ |
414 | | - public function getModuleStyles() { |
415 | | - return array_values( array_unique( $this->mModuleStyles ) ); |
| 429 | + public function getModuleStyles( $filter = false ) { |
| 430 | + return $this->getModules( $filter, 'mModuleStyles' ); |
416 | 431 | } |
417 | 432 | |
418 | 433 | /** |
— | — | @@ -430,8 +445,8 @@ |
431 | 446 | * |
432 | 447 | * @return Array of module names |
433 | 448 | */ |
434 | | - public function getModuleMessages() { |
435 | | - return array_values( array_unique( $this->mModuleMessages ) ); |
| 449 | + public function getModuleMessages( $filter = false ) { |
| 450 | + return $this->getModules( $filter, 'mModuleMessages' ); |
436 | 451 | } |
437 | 452 | |
438 | 453 | /** |
— | — | @@ -1065,22 +1080,61 @@ |
1066 | 1081 | } |
1067 | 1082 | |
1068 | 1083 | /** |
1069 | | - * Remove user JavaScript from scripts to load |
| 1084 | + * Do not allow scripts which can be modified by wiki users to load on this page; |
| 1085 | + * only allow scripts bundled with, or generated by, the software. |
1070 | 1086 | */ |
1071 | 1087 | public function disallowUserJs() { |
1072 | | - $this->mAllowUserJs = false; |
| 1088 | + $this->reduceAllowedModules( |
| 1089 | + ResourceLoaderModule::TYPE_SCRIPTS, |
| 1090 | + ResourceLoaderModule::ORIGIN_CORE_INDIVIDUAL |
| 1091 | + ); |
1073 | 1092 | } |
1074 | 1093 | |
1075 | 1094 | /** |
1076 | 1095 | * Return whether user JavaScript is allowed for this page |
1077 | | - * |
| 1096 | + * @deprecated @since 1.18 Load modules with ResourceLoader, and origin and |
| 1097 | + * trustworthiness is identified and enforced automagically. |
1078 | 1098 | * @return Boolean |
1079 | 1099 | */ |
1080 | 1100 | public function isUserJsAllowed() { |
1081 | | - return $this->mAllowUserJs; |
| 1101 | + return $this->getAllowedModules( ResourceLoaderModule::TYPE_SCRIPTS ) >= ResourceLoaderModule::ORIGIN_USER_INDIVIDUAL; |
1082 | 1102 | } |
1083 | 1103 | |
1084 | 1104 | /** |
| 1105 | + * Show what level of JavaScript / CSS untrustworthiness is allowed on this page |
| 1106 | + * @see ResourceLoaderModule::$origin |
| 1107 | + * @param $type String ResourceLoaderModule TYPE_ constant |
| 1108 | + * @return Int ResourceLoaderModule ORIGIN_ class constant |
| 1109 | + */ |
| 1110 | + public function getAllowedModules( $type ){ |
| 1111 | + if( $type == ResourceLoaderModule::TYPE_COMBINED ){ |
| 1112 | + return min( array_values( $this->mAllowedModules ) ); |
| 1113 | + } else { |
| 1114 | + return isset( $this->mAllowedModules[$type] ) |
| 1115 | + ? $this->mAllowedModules[$type] |
| 1116 | + : ResourceLoaderModule::ORIGIN_ALL; |
| 1117 | + } |
| 1118 | + } |
| 1119 | + |
| 1120 | + /** |
| 1121 | + * Set the highest level of CSS/JS untrustworthiness allowed |
| 1122 | + * @param $type String ResourceLoaderModule TYPE_ constant |
| 1123 | + * @param $level Int ResourceLoaderModule class constant |
| 1124 | + */ |
| 1125 | + public function setAllowedModules( $type, $level ){ |
| 1126 | + $this->mAllowedModules[$type] = $level; |
| 1127 | + } |
| 1128 | + |
| 1129 | + /** |
| 1130 | + * As for setAllowedModules(), but don't inadvertantly make the page more accessible |
| 1131 | + * @param $type String |
| 1132 | + * @param $level Int ResourceLoaderModule class constant |
| 1133 | + */ |
| 1134 | + public function reduceAllowedModules( $type, $level ){ |
| 1135 | + $this->mAllowedModules[$type] = min( $this->getAllowedModules($type), $level ); |
| 1136 | + } |
| 1137 | + |
| 1138 | + /** |
1085 | 1139 | * Prepend $text to the body HTML |
1086 | 1140 | * |
1087 | 1141 | * @param $text String: HTML |
— | — | @@ -2347,7 +2401,7 @@ |
2348 | 2402 | * TODO: Document |
2349 | 2403 | * @param $skin Skin |
2350 | 2404 | * @param $modules Array/string with the module name |
2351 | | - * @param $only string May be styles, messages or scripts |
| 2405 | + * @param $only String ResourceLoaderModule TYPE_ class constant |
2352 | 2406 | * @param $useESI boolean |
2353 | 2407 | * @return string html <script> and <style> tags |
2354 | 2408 | */ |
— | — | @@ -2396,12 +2450,23 @@ |
2397 | 2451 | $resourceLoader = $this->getResourceLoader(); |
2398 | 2452 | foreach ( (array) $modules as $name ) { |
2399 | 2453 | $module = $resourceLoader->getModule( $name ); |
| 2454 | + # Check that we're allowed to include this module on this page |
| 2455 | + if( ( $module->getOrigin() > $this->getAllowedModules( ResourceLoaderModule::TYPE_SCRIPTS ) |
| 2456 | + && $only == ResourceLoaderModule::TYPE_SCRIPTS ) |
| 2457 | + || ( $module->getOrigin() > $this->getAllowedModules( ResourceLoaderModule::TYPE_STYLES ) |
| 2458 | + && $only == ResourceLoaderModule::TYPE_STYLES ) |
| 2459 | + ) |
| 2460 | + { |
| 2461 | + continue; |
| 2462 | + } |
| 2463 | + |
2400 | 2464 | $group = $module->getGroup(); |
2401 | 2465 | if ( !isset( $groups[$group] ) ) { |
2402 | 2466 | $groups[$group] = array(); |
2403 | 2467 | } |
2404 | 2468 | $groups[$group][$name] = $module; |
2405 | 2469 | } |
| 2470 | + |
2406 | 2471 | $links = ''; |
2407 | 2472 | foreach ( $groups as $group => $modules ) { |
2408 | 2473 | $query['modules'] = implode( '|', array_keys( $modules ) ); |
— | — | @@ -2412,7 +2477,7 @@ |
2413 | 2478 | // Support inlining of private modules if configured as such |
2414 | 2479 | if ( $group === 'private' && $wgResourceLoaderInlinePrivateModules ) { |
2415 | 2480 | $context = new ResourceLoaderContext( $resourceLoader, new FauxRequest( $query ) ); |
2416 | | - if ( $only == 'styles' ) { |
| 2481 | + if ( $only == ResourceLoaderModule::TYPE_STYLES ) { |
2417 | 2482 | $links .= Html::inlineStyle( |
2418 | 2483 | $resourceLoader->makeModuleResponse( $context, $modules ) |
2419 | 2484 | ); |
— | — | @@ -2446,14 +2511,14 @@ |
2447 | 2512 | $url = wfAppendQuery( $wgLoadScript, $query ); |
2448 | 2513 | if ( $useESI && $wgResourceLoaderUseESI ) { |
2449 | 2514 | $esi = Xml::element( 'esi:include', array( 'src' => $url ) ); |
2450 | | - if ( $only == 'styles' ) { |
| 2515 | + if ( $only == ResourceLoaderModule::TYPE_STYLES ) { |
2451 | 2516 | $links .= Html::inlineStyle( $esi ); |
2452 | 2517 | } else { |
2453 | 2518 | $links .= Html::inlineScript( $esi ); |
2454 | 2519 | } |
2455 | 2520 | } else { |
2456 | 2521 | // Automatically select style/script elements |
2457 | | - if ( $only === 'styles' ) { |
| 2522 | + if ( $only === ResourceLoaderModule::TYPE_STYLES ) { |
2458 | 2523 | $links .= Html::linkedStyle( wfAppendQuery( $wgLoadScript, $query ) ) . "\n"; |
2459 | 2524 | } else { |
2460 | 2525 | $links .= Html::linkedScript( wfAppendQuery( $wgLoadScript, $query ) ) . "\n"; |
— | — | @@ -2472,24 +2537,24 @@ |
2473 | 2538 | * @return String: HTML fragment |
2474 | 2539 | */ |
2475 | 2540 | function getHeadScripts( Skin $sk ) { |
2476 | | - global $wgUser, $wgRequest, $wgUseSiteJs; |
| 2541 | + global $wgUser, $wgRequest, $wgUseSiteJs, $wgAllowUserJs; |
2477 | 2542 | |
2478 | 2543 | // Startup - this will immediately load jquery and mediawiki modules |
2479 | | - $scripts = $this->makeResourceLoaderLink( $sk, 'startup', 'scripts', true ); |
| 2544 | + $scripts = $this->makeResourceLoaderLink( $sk, 'startup', ResourceLoaderModule::TYPE_SCRIPTS, true ); |
2480 | 2545 | |
2481 | 2546 | // Configuration -- This could be merged together with the load and go, but |
2482 | 2547 | // makeGlobalVariablesScript returns a whole script tag -- grumble grumble... |
2483 | 2548 | $scripts .= Skin::makeGlobalVariablesScript( $sk->getSkinName() ) . "\n"; |
2484 | 2549 | |
2485 | 2550 | // Script and Messages "only" requests |
2486 | | - $scripts .= $this->makeResourceLoaderLink( $sk, $this->getModuleScripts(), 'scripts' ); |
2487 | | - $scripts .= $this->makeResourceLoaderLink( $sk, $this->getModuleMessages(), 'messages' ); |
| 2551 | + $scripts .= $this->makeResourceLoaderLink( $sk, $this->getModuleScripts( true ), ResourceLoaderModule::TYPE_SCRIPTS ); |
| 2552 | + $scripts .= $this->makeResourceLoaderLink( $sk, $this->getModuleMessages( true ), ResourceLoaderModule::TYPE_MESSAGES ); |
2488 | 2553 | |
2489 | 2554 | // Modules requests - let the client calculate dependencies and batch requests as it likes |
2490 | | - if ( $this->getModules() ) { |
| 2555 | + if ( $this->getModules( true ) ) { |
2491 | 2556 | $scripts .= Html::inlineScript( |
2492 | 2557 | ResourceLoader::makeLoaderConditionalScript( |
2493 | | - Xml::encodeJsCall( 'mediaWiki.loader.load', array( $this->getModules() ) ) . |
| 2558 | + Xml::encodeJsCall( 'mediaWiki.loader.load', array( $this->getModules( true ) ) ) . |
2494 | 2559 | Xml::encodeJsCall( 'mediaWiki.loader.go', array() ) |
2495 | 2560 | ) |
2496 | 2561 | ) . "\n"; |
— | — | @@ -2500,25 +2565,25 @@ |
2501 | 2566 | |
2502 | 2567 | // Add site JS if enabled |
2503 | 2568 | if ( $wgUseSiteJs ) { |
2504 | | - $scripts .= $this->makeResourceLoaderLink( $sk, 'site', 'scripts' ); |
| 2569 | + $scripts .= $this->makeResourceLoaderLink( $sk, 'site', ResourceLoaderModule::TYPE_SCRIPTS ); |
2505 | 2570 | } |
2506 | 2571 | |
2507 | 2572 | // Add user JS if enabled - trying to load user.options as a bundle if possible |
2508 | 2573 | $userOptionsAdded = false; |
2509 | | - if ( $this->isUserJsAllowed() && $wgUser->isLoggedIn() ) { |
| 2574 | + if ( $wgAllowUserJs && $wgUser->isLoggedIn() ) { |
2510 | 2575 | $action = $wgRequest->getVal( 'action', 'view' ); |
2511 | 2576 | if( $this->mTitle && $this->mTitle->isJsSubpage() && $sk->userCanPreview( $action ) ) { |
2512 | 2577 | # XXX: additional security check/prompt? |
2513 | 2578 | $scripts .= Html::inlineScript( "\n" . $wgRequest->getText( 'wpTextbox1' ) . "\n" ) . "\n"; |
2514 | 2579 | } else { |
2515 | 2580 | $scripts .= $this->makeResourceLoaderLink( |
2516 | | - $sk, array( 'user', 'user.options' ), 'scripts' |
| 2581 | + $sk, array( 'user', 'user.options' ), ResourceLoaderModule::TYPE_SCRIPTS |
2517 | 2582 | ); |
2518 | 2583 | $userOptionsAdded = true; |
2519 | 2584 | } |
2520 | 2585 | } |
2521 | 2586 | if ( !$userOptionsAdded ) { |
2522 | | - $scripts .= $this->makeResourceLoaderLink( $sk, 'user.options', 'scripts' ); |
| 2587 | + $scripts .= $this->makeResourceLoaderLink( $sk, 'user.options', ResourceLoaderModule::TYPE_SCRIPTS ); |
2523 | 2588 | } |
2524 | 2589 | |
2525 | 2590 | return $scripts; |
— | — | @@ -2713,7 +2778,7 @@ |
2714 | 2779 | // dynamically added styles to override statically added styles from other modules. So the order |
2715 | 2780 | // has to be other, dynamic, site, user |
2716 | 2781 | // Add statically added styles for other modules |
2717 | | - $ret .= $this->makeResourceLoaderLink( $sk, $styles['other'], 'styles' ); |
| 2782 | + $ret .= $this->makeResourceLoaderLink( $sk, $styles['other'], ResourceLoaderModule::TYPE_STYLES ); |
2718 | 2783 | // Add normal styles added through addStyle()/addInlineStyle() here |
2719 | 2784 | $ret .= implode( "\n", $this->buildCssLinksArray() ) . $this->mInlineStyles; |
2720 | 2785 | // Add marker tag to mark the place where the client-side loader should inject dynamic styles |
— | — | @@ -2721,7 +2786,7 @@ |
2722 | 2787 | $ret .= Html::element( 'meta', array( 'name' => 'ResourceLoaderDynamicStyles', 'content' => '' ) ); |
2723 | 2788 | // Add site and user styles |
2724 | 2789 | $ret .= $this->makeResourceLoaderLink( |
2725 | | - $sk, array_merge( $styles['site'], $styles['user'] ), 'styles' |
| 2790 | + $sk, array_merge( $styles['site'], $styles['user'] ), ResourceLoaderModule::TYPE_STYLES |
2726 | 2791 | ); |
2727 | 2792 | return $ret; |
2728 | 2793 | } |
Index: trunk/phase3/includes/resourceloader/ResourceLoaderWikiModule.php |
— | — | @@ -32,6 +32,9 @@ |
33 | 33 | abstract class ResourceLoaderWikiModule extends ResourceLoaderModule { |
34 | 34 | |
35 | 35 | /* Protected Members */ |
| 36 | + |
| 37 | + # Origin is user-supplied code |
| 38 | + protected $origin = self::ORIGIN_USER_SITEWIDE; |
36 | 39 | |
37 | 40 | // In-object cache for modified time |
38 | 41 | protected $modifiedTime = array(); |
Index: trunk/phase3/includes/resourceloader/ResourceLoaderUserOptionsModule.php |
— | — | @@ -29,6 +29,8 @@ |
30 | 30 | |
31 | 31 | protected $modifiedTime = array(); |
32 | 32 | |
| 33 | + protected $origin = self::ORIGIN_CORE_INDIVIDUAL; |
| 34 | + |
33 | 35 | /* Methods */ |
34 | 36 | |
35 | 37 | public function getModifiedTime( ResourceLoaderContext $context ) { |
Index: trunk/phase3/includes/resourceloader/ResourceLoaderUserModule.php |
— | — | @@ -26,6 +26,7 @@ |
27 | 27 | class ResourceLoaderUserModule extends ResourceLoaderWikiModule { |
28 | 28 | |
29 | 29 | /* Protected Methods */ |
| 30 | + protected $origin = self::ORIGIN_USER_INDIVIDUAL; |
30 | 31 | |
31 | 32 | protected function getPages( ResourceLoaderContext $context ) { |
32 | 33 | if ( $context->getUser() ) { |
Index: trunk/phase3/includes/resourceloader/ResourceLoaderModule.php |
— | — | @@ -24,6 +24,34 @@ |
25 | 25 | * Abstraction for resource loader modules, with name registration and maxage functionality. |
26 | 26 | */ |
27 | 27 | abstract class ResourceLoaderModule { |
| 28 | + |
| 29 | + # Type of resource |
| 30 | + const TYPE_SCRIPTS = 'scripts'; |
| 31 | + const TYPE_STYLES = 'styles'; |
| 32 | + const TYPE_MESSAGES = 'messages'; |
| 33 | + const TYPE_COMBINED = 'combined'; |
| 34 | + |
| 35 | + # sitewide core module like a skin file or jQuery component |
| 36 | + const ORIGIN_CORE_SITEWIDE = 1; |
| 37 | + |
| 38 | + # per-user module generated by the software |
| 39 | + const ORIGIN_CORE_INDIVIDUAL = 2; |
| 40 | + |
| 41 | + # sitewide module generated from user-editable files, like MediaWiki:Common.js, or |
| 42 | + # modules accessible to multiple users, such as those generated by the Gadgets extension. |
| 43 | + const ORIGIN_USER_SITEWIDE = 3; |
| 44 | + |
| 45 | + # per-user module generated from user-editable files, like User:Me/Monobook.js |
| 46 | + const ORIGIN_USER_INDIVIDUAL = 4; |
| 47 | + |
| 48 | + # an access constant; make sure this is kept as the largest number in this group |
| 49 | + const ORIGIN_ALL = 10; |
| 50 | + |
| 51 | + # script and style modules form a hierarchy of trustworthiness, with core modules like |
| 52 | + # skins and jQuery as most trustworthy, and user scripts as least trustworthy. We can |
| 53 | + # limit the types of scripts and styles we allow to load on, say, sensitive special |
| 54 | + # pages like Special:UserLogin and Special:Preferences |
| 55 | + protected $origin = self::ORIGIN_CORE_SITEWIDE; |
28 | 56 | |
29 | 57 | /* Protected Members */ |
30 | 58 | |
— | — | @@ -57,6 +85,27 @@ |
58 | 86 | } |
59 | 87 | |
60 | 88 | /** |
| 89 | + * Get this module's origin. This is set when the module is registered |
| 90 | + * with ResourceLoader::register() |
| 91 | + * |
| 92 | + * @return Int ResourceLoaderModule class constant, the subclass default |
| 93 | + * if not set manuall |
| 94 | + */ |
| 95 | + public function getOrigin() { |
| 96 | + return $this->origin; |
| 97 | + } |
| 98 | + |
| 99 | + /** |
| 100 | + * Set this module's origin. This is called by ResourceLodaer::register() |
| 101 | + * when registering the module. Other code should not call this. |
| 102 | + * |
| 103 | + * @param $name Int origin |
| 104 | + */ |
| 105 | + public function setOrigin( $origin ) { |
| 106 | + $this->origin = $origin; |
| 107 | + } |
| 108 | + |
| 109 | + /** |
61 | 110 | * Get whether CSS for this module should be flipped |
62 | 111 | * @param $context ResourceLoaderContext |
63 | 112 | */ |
Index: trunk/phase3/includes/SkinTemplate.php |
— | — | @@ -201,6 +201,8 @@ |
202 | 202 | $tpl->setRef( 'usercss', $this->usercss ); |
203 | 203 | |
204 | 204 | $this->userjs = $this->userjsprev = false; |
| 205 | + # FIXME: this is the only use of OutputPage::isUserJsAllowed() anywhere; can we |
| 206 | + # get rid of it? For that matter, why is any of this here at all? |
205 | 207 | $this->setupUserJs( $out->isUserJsAllowed() ); |
206 | 208 | $tpl->setRef( 'userjs', $this->userjs ); |
207 | 209 | $tpl->setRef( 'userjsprev', $this->userjsprev ); |
— | — | @@ -1255,6 +1257,7 @@ |
1256 | 1258 | |
1257 | 1259 | /** |
1258 | 1260 | * @private |
| 1261 | + * FIXME: why is this duplicated in/from OutputPage::getHeadScripts()?? |
1259 | 1262 | */ |
1260 | 1263 | function setupUserJs( $allowUserJs ) { |
1261 | 1264 | global $wgRequest, $wgJsMimeType; |
Index: trunk/extensions/Gadgets/Gadgets_body.php |
— | — | @@ -106,19 +106,6 @@ |
107 | 107 | if ( !$wgUser->isLoggedIn() ) return true; |
108 | 108 | |
109 | 109 | wfProfileIn( __METHOD__ ); |
110 | | - //disable all gadgets on critical special pages |
111 | | - //NOTE: $out->isUserJsAllowed() is tempting, but always fals if $wgAllowUserJs is false. |
112 | | - // That would disable gadgets on wikis without user JS. Introducing $out->isJsAllowed() |
113 | | - // may work, but should that really apply also to MediaWiki:common.js? Even on the preference page? |
114 | | - // See bug 22929 for discussion. |
115 | | - $title = $out->getTitle(); |
116 | | - if ( $title->isSpecial( 'Preferences' ) |
117 | | - || $title->isSpecial( 'Resetpass' ) |
118 | | - || $title->isSpecial( 'Userlogin' ) ) |
119 | | - { |
120 | | - wfProfileOut( __METHOD__ ); |
121 | | - return true; |
122 | | - } |
123 | 110 | |
124 | 111 | $gadgets = Gadget::loadList(); |
125 | 112 | if ( !$gadgets ) { |
— | — | @@ -164,6 +151,14 @@ |
165 | 152 | private static function applyScript( $page, $out ) { |
166 | 153 | global $wgJsMimeType; |
167 | 154 | |
| 155 | + # bug 22929: disable gadgets on sensitive pages. Scripts loaded through the |
| 156 | + # ResourceLoader handle this in OutputPage::getModules() |
| 157 | + # TODO: make this extension load everything via RL, then we don't need to worry |
| 158 | + # about any of this. |
| 159 | + if( $out->getAllowedModules( ResourceLoaderModule::TYPE_SCRIPTS ) < ResourceLoaderModule::ORIGIN_USER_SITEWIDE ){ |
| 160 | + return; |
| 161 | + } |
| 162 | + |
168 | 163 | $t = Title::makeTitleSafe( NS_MEDIAWIKI, $page ); |
169 | 164 | if ( !$t ) return; |
170 | 165 | |