Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
90.91% covered (success)
90.91%
50 / 55
71.43% covered (warning)
71.43%
5 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
CaptchaAuthenticationRequest
90.91% covered (success)
90.91%
50 / 55
71.43% covered (warning)
71.43%
5 / 7
12.11
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getUniqueId
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 loadFromSubmission
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
3
 getActionForMessage
42.86% covered (danger)
42.86%
3 / 7
0.00% covered (danger)
0.00%
0 / 1
4.68
 getFieldInfo
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
1 / 1
1
 getMetadata
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 __set_state
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare( strict_types=1 );
4
5namespace MediaWiki\Extension\ConfirmEdit\Auth;
6
7use MediaWiki\Auth\AuthenticationRequest;
8use MediaWiki\Auth\AuthManager;
9use MediaWiki\Context\RequestContext;
10use MediaWiki\Extension\ConfirmEdit\CaptchaTriggers;
11use MediaWiki\Extension\ConfirmEdit\Services\CaptchaFactory;
12use MediaWiki\MediaWikiServices;
13
14/**
15 * Generic captcha authentication request class.
16 *
17 *  A captcha consists of some data stored in the session
18 * (e.g. a question and its answer), an ID that references the data, and a solution.
19 */
20class CaptchaAuthenticationRequest extends AuthenticationRequest {
21    /** @var string Identifier of the captcha. Used internally to remember which captcha was used. */
22    public $captchaId;
23
24    /** @var array Information about the captcha (e.g. question text; solution). Exact semantics
25     *    differ between types.
26     */
27    public $captchaData;
28
29    /** @var string Captcha solution submitted by the user. */
30    public $captchaWord;
31
32    /**
33     * @param string $id
34     * @param array $data
35     */
36    public function __construct( $id, $data ) {
37        $this->captchaId = $id;
38        $this->captchaData = $data;
39    }
40
41    /** @inheritDoc */
42    public function getUniqueId() {
43        return 'CaptchaAuthenticationRequest';
44    }
45
46    /** @inheritDoc */
47    public function loadFromSubmission( array $data ) {
48        $success = parent::loadFromSubmission( $data );
49        if ( $success ) {
50            // The captchaId and captchaWord were set from the submission, but captchaData was not.
51            /** @var CaptchaFactory $captchaFactory */
52            $captchaFactory = MediaWikiServices::getInstance()->get( 'ConfirmEditCaptchaFactory' );
53            $captcha = $captchaFactory->getGlobalInstanceFromAuthenticationRequest(
54                $this,
55                RequestContext::getMain()->getRequest()->getSession()
56            );
57            $this->captchaData = $captcha->retrieveCaptcha( $this->captchaId );
58            if ( !$this->captchaData ) {
59                return false;
60            }
61        }
62        return $success;
63    }
64
65    public function getActionForMessage(): string {
66        // generic action doesn't exist, but *Captcha::getMessage will handle that
67        $action = 'generic';
68        switch ( $this->action ) {
69            case AuthManager::ACTION_LOGIN:
70                $action = CaptchaTriggers::BAD_LOGIN;
71                break;
72            case AuthManager::ACTION_CREATE:
73                $action = CaptchaTriggers::CREATE_ACCOUNT;
74                break;
75        }
76        return $action;
77    }
78
79    /** @inheritDoc */
80    public function getFieldInfo() {
81        /** @var CaptchaFactory $captchaFactory */
82        $captchaFactory = MediaWikiServices::getInstance()->get( 'ConfirmEditCaptchaFactory' );
83        $captcha = $captchaFactory->getGlobalInstanceFromAuthenticationRequest(
84            $this,
85            RequestContext::getMain()->getRequest()->getSession()
86        );
87
88        return [
89            'captchaId' => [
90                'type' => 'hidden',
91                'value' => $this->captchaId,
92                'label' => wfMessage( 'captcha-id-label' ),
93                'help' => wfMessage( 'captcha-id-help' ),
94            ],
95            'captchaInfo' => [
96                'type' => 'null',
97                'label' => $captcha->getMessage( $this->getActionForMessage() ),
98                'value' => $captcha->getCaptchaInfo( $this->captchaData, $this->captchaId ),
99                'help' => wfMessage( 'captcha-info-help' ),
100            ],
101            'captchaWord' => [
102                'type' => 'string',
103                'label' => wfMessage( 'captcha-label' ),
104                'help' => wfMessage( 'captcha-help' ),
105            ],
106        ];
107    }
108
109    /** @inheritDoc */
110    public function getMetadata() {
111        /** @var CaptchaFactory $captchaFactory */
112        $captchaFactory = MediaWikiServices::getInstance()->get( 'ConfirmEditCaptchaFactory' );
113        $captcha = $captchaFactory->getGlobalInstanceFromAuthenticationRequest(
114            $this,
115            RequestContext::getMain()->getRequest()->getSession()
116        );
117        return $captcha->describeCaptchaType();
118    }
119
120    /**
121     * @param array $data
122     * @return CaptchaAuthenticationRequest
123     */
124    public static function __set_state( $data ) {
125        $ret = new static( '', [] );
126        foreach ( $data as $k => $v ) {
127            $ret->$k = $v;
128        }
129        return $ret;
130    }
131}