abstract class FormSpecialPage extends SpecialPage {
/**
* The sub-page of the special page.
- * @var string
+ * @var string|null
*/
protected $par = null;
+ /**
+ * @var array|null POST data preserved across re-authentication
+ * @since 1.32
+ */
+ protected $reauthPostData = null;
+
/**
* Get an HTMLForm descriptor array
* @return array
* @return HTMLForm|null
*/
protected function getForm() {
+ $context = $this->getContext();
+ $onSubmit = [ $this, 'onSubmit' ];
+
+ if ( $this->reauthPostData ) {
+ // Restore POST data
+ $context = new DerivativeContext( $context );
+ $oldRequest = $this->getRequest();
+ $context->setRequest( new DerivativeRequest(
+ $oldRequest, $this->reauthPostData + $oldRequest->getQueryValues(), true
+ ) );
+
+ // But don't treat it as a "real" submission just in case of some
+ // crazy kind of CSRF.
+ $onSubmit = function () {
+ return false;
+ };
+ }
+
$form = HTMLForm::factory(
$this->getDisplayFormat(),
$this->getFormFields(),
- $this->getContext(),
+ $context,
$this->getMessagePrefix()
);
- $form->setSubmitCallback( [ $this, 'onSubmit' ] );
+ $form->setSubmitCallback( $onSubmit );
if ( $this->getDisplayFormat() !== 'ooui' ) {
// No legend and wrapper by default in OOUI forms, but can be set manually
// from alterForm()
/**
* Basic SpecialPage workflow: get a form, send it to the user; get some data back,
*
- * @param string $par Subpage string if one was specified
+ * @param string|null $par Subpage string if one was specified
*/
public function execute( $par ) {
$this->setParameter( $par );
// This will throw exceptions if there's a problem
$this->checkExecutePermissions( $this->getUser() );
+ $securityLevel = $this->getLoginSecurityLevel();
+ if ( $securityLevel !== false && !$this->checkLoginSecurityLevel( $securityLevel ) ) {
+ return;
+ }
+
$form = $this->getForm();
if ( $form->show() ) {
$this->onSuccess();
/**
* Maybe do something interesting with the subpage parameter
- * @param string $par
+ * @param string|null $par
*/
protected function setParameter( $par ) {
$this->par = $par;
protected function checkExecutePermissions( User $user ) {
$this->checkPermissions();
- if ( $this->requiresUnblock() && $user->isBlocked() ) {
+ if ( $this->requiresUnblock() ) {
$block = $user->getBlock();
- throw new UserBlockedError( $block );
+ if ( $block && $block->isSitewide() ) {
+ throw new UserBlockedError( $block );
+ }
}
if ( $this->requiresWrite() ) {
public function requiresUnblock() {
return true;
}
+
+ /**
+ * Preserve POST data across reauthentication
+ *
+ * @since 1.32
+ * @param array $data
+ */
+ protected function setReauthPostData( array $data ) {
+ $this->reauthPostData = $data;
+ }
}