/**
* Get or set whether this special page is listed in Special:SpecialPages
* @since 1.6
- * @param bool $x
+ * @param bool|null $x
* @return bool
*/
function listed( $x = null ) {
/**
* Whether the special page is being evaluated via transclusion
- * @param bool $x
+ * @param bool|null $x
* @return bool
*/
function including( $x = null ) {
return false;
}
+ /**
+ * Record preserved POST data after a reauthentication.
+ *
+ * This is called from checkLoginSecurityLevel() when returning from the
+ * redirect for reauthentication, if the redirect had been served in
+ * response to a POST request.
+ *
+ * The base SpecialPage implementation does nothing. If your subclass uses
+ * getLoginSecurityLevel() or checkLoginSecurityLevel(), it should probably
+ * implement this to do something with the data.
+ *
+ * @since 1.32
+ * @param array $data
+ */
+ protected function setReauthPostData( array $data ) {
+ }
+
/**
* Verifies that the user meets the security level, possibly reauthenticating them in the process.
*
* Note that this does not in any way check that the user is authorized to use this special page
* (use checkPermissions() for that).
*
- * @param string $level A security level. Can be an arbitrary string, defaults to the page name.
+ * @param string|null $level A security level. Can be an arbitrary string, defaults to the page
+ * name.
* @return bool False means a redirect to the reauthentication page has been set and processing
* of the special page should be aborted.
* @throws ErrorPageError If the security level cannot be met, even with reauthentication.
*/
protected function checkLoginSecurityLevel( $level = null ) {
$level = $level ?: $this->getName();
+ $key = 'SpecialPage:reauth:' . $this->getName();
+ $request = $this->getRequest();
+
$securityStatus = AuthManager::singleton()->securitySensitiveOperationStatus( $level );
if ( $securityStatus === AuthManager::SEC_OK ) {
+ $uniqueId = $request->getVal( 'postUniqueId' );
+ if ( $uniqueId ) {
+ $key = $key . ':' . $uniqueId;
+ $session = $request->getSession();
+ $data = $session->getSecret( $key );
+ if ( $data ) {
+ $session->remove( $key );
+ $this->setReauthPostData( $data );
+ }
+ }
return true;
} elseif ( $securityStatus === AuthManager::SEC_REAUTH ) {
- $request = $this->getRequest();
$title = self::getTitleFor( 'Userlogin' );
+ $queryParams = $request->getQueryValues();
+
+ if ( $request->wasPosted() ) {
+ $data = array_diff_assoc( $request->getValues(), $request->getQueryValues() );
+ if ( $data ) {
+ // unique ID in case the same special page is open in multiple browser tabs
+ $uniqueId = MWCryptRand::generateHex( 6 );
+ $key = $key . ':' . $uniqueId;
+ $queryParams['postUniqueId'] = $uniqueId;
+ $session = $request->getSession();
+ $session->persist(); // Just in case
+ $session->setSecret( $key, $data );
+ }
+ }
+
$query = [
'returnto' => $this->getFullTitle()->getPrefixedDBkey(),
- 'returntoquery' => wfArrayToCgi( array_diff_key( $request->getQueryValues(),
- [ 'title' => true ] ) ),
+ 'returntoquery' => wfArrayToCgi( array_diff_key( $queryParams, [ 'title' => true ] ) ),
'force' => $level,
];
$url = $title->getFullURL( $query, false, PROTO_HTTPS );
public function execute( $subPage ) {
$this->setHeaders();
$this->checkPermissions();
- $this->checkLoginSecurityLevel( $this->getLoginSecurityLevel() );
+ $securityLevel = $this->getLoginSecurityLevel();
+ if ( $securityLevel !== false && !$this->checkLoginSecurityLevel( $securityLevel ) ) {
+ return;
+ }
$this->outputHeader();
}
* @param string $summaryMessageKey Message key of the summary
*/
function outputHeader( $summaryMessageKey = '' ) {
- global $wgContLang;
-
if ( $summaryMessageKey == '' ) {
- $msg = $wgContLang->lc( $this->getName() ) . '-summary';
+ $msg = MediaWikiServices::getInstance()->getContentLanguage()->lc( $this->getName() ) .
+ '-summary';
} else {
$msg = $summaryMessageKey;
}
* @see wfMessage
*/
public function msg( $key /* $args */ ) {
- $message = call_user_func_array(
- [ $this->getContext(), 'msg' ],
- func_get_args()
- );
+ $message = $this->getContext()->msg( ...func_get_args() );
// RequestContext passes context to wfMessage, and the language is set from
// the context, but setting the language for Message class removes the
// interface message status, which breaks for example usernameless gender
return;
}
- global $wgContLang;
- $msg = $this->msg( $wgContLang->lc( $this->getName() ) . '-helppage' );
+ $msg = $this->msg(
+ MediaWikiServices::getInstance()->getContentLanguage()->lc( $this->getName() ) .
+ '-helppage' );
if ( !$msg->isDisabled() ) {
$helpUrl = Skin::makeUrl( $msg->plain() );