1<?php
2
3use MediaWiki\Auth\AuthenticationRequest;
4use MediaWiki\Auth\AuthManager;
5
6/**
7 * Generic captcha authentication request class. A captcha consist some data stored in the session
8 * (e.g. a question and its answer), an ID that references the data, and a solution.
9 */
10class CaptchaAuthenticationRequest extends AuthenticationRequest {
11	/** @var string Identifier of the captcha. Used internally to remember which captcha was used. */
12	public $captchaId;
13
14	/** @var array Information about the captcha (e.g. question text; solution). Exact semantics
15	 *    differ between types.
16	 */
17	public $captchaData;
18
19	/** @var string Captcha solution submitted by the user. */
20	public $captchaWord;
21
22	/**
23	 * @param string $id
24	 * @param array $data
25	 */
26	public function __construct( $id, $data ) {
27		$this->captchaId = $id;
28		$this->captchaData = $data;
29	}
30
31	/**
32	 * @inheritDoc
33	 */
34	public function loadFromSubmission( array $data ) {
35		$success = parent::loadFromSubmission( $data );
36		if ( $success ) {
37			// captchaId and captchaWord was set from the submission but captchaData was not.
38			$captcha = ConfirmEditHooks::getInstance();
39			$this->captchaData = $captcha->retrieveCaptcha( $this->captchaId );
40			if ( !$this->captchaData ) {
41				return false;
42			}
43		}
44		return $success;
45	}
46
47	/**
48	 * @inheritDoc
49	 */
50	public function getFieldInfo() {
51		$captcha = ConfirmEditHooks::getInstance();
52
53		// doesn't actually exist but *Captcha::getMessage will handle that
54		$action = 'generic';
55		switch ( $this->action ) {
56			case AuthManager::ACTION_LOGIN:
57				$action = 'badlogin';
58				break;
59			case AuthManager::ACTION_CREATE:
60				$action = 'createaccount';
61				break;
62		}
63
64		$fields = [
65			'captchaId' => [
66				'type' => 'hidden',
67				'value' => $this->captchaId,
68				'label' => wfMessage( 'captcha-id-label' ),
69				'help' => wfMessage( 'captcha-id-help' ),
70			],
71			'captchaInfo' => [
72				'type' => 'null',
73				'label' => $captcha->getMessage( $action ),
74				'value' => $captcha->getCaptchaInfo( $this->captchaData, $this->captchaId ),
75				'help' => wfMessage( 'captcha-info-help' ),
76			],
77			'captchaWord' => [
78				'type' => 'string',
79				'label' => wfMessage( 'captcha-label' ),
80				'help' => wfMessage( 'captcha-help' ),
81			],
82		];
83
84		return $fields;
85	}
86
87	/**
88	 * @inheritDoc
89	 */
90	public function getMetadata() {
91		return ( ConfirmEditHooks::getInstance() )->describeCaptchaType();
92	}
93
94	/**
95	 * @param array $data
96	 * @return CaptchaAuthenticationRequest
97	 */
98	public static function __set_state( $data ) {
99		$ret = new static( '', [] );
100		foreach ( $data as $k => $v ) {
101			$ret->$k = $v;
102		}
103		return $ret;
104	}
105}
106