Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 62
0.00% covered (danger)
0.00%
0 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
VerifyOATHForUser
0.00% covered (danger)
0.00%
0 / 62
0.00% covered (danger)
0.00%
0 / 11
306
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getGroupName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 doesWrites
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getLoginSecurityLevel
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 alterForm
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getDisplayFormat
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 requiresUnblock
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getFormFields
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
2
 onSubmit
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
20
 onSuccess
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3namespace MediaWiki\Extension\OATHAuth\Special;
4
5use HTMLForm;
6use ManualLogEntry;
7use MediaWiki\Config\ConfigException;
8use MediaWiki\Extension\OATHAuth\OATHUserRepository;
9use MediaWiki\Logger\LoggerFactory;
10use MediaWiki\SpecialPage\FormSpecialPage;
11use MediaWiki\User\UserFactory;
12use MWException;
13
14class VerifyOATHForUser extends FormSpecialPage {
15
16    private const OATHAUTH_IS_ENABLED = 'enabled';
17    private const OATHAUTH_NOT_ENABLED = 'disabled';
18    private OATHUserRepository $userRepo;
19    private UserFactory $userFactory;
20
21    /** @var string */
22    private $enabledStatus;
23
24    /** @var string */
25    private $targetUser;
26
27    /**
28     * @param OATHUserRepository $userRepo
29     * @param UserFactory $userFactory
30     */
31    public function __construct( $userRepo, $userFactory ) {
32        // messages used: verifyoathforuser (display "name" on Special:SpecialPages),
33        // right-oathauth-verify-user, action-oathauth-verify-user
34        parent::__construct( 'VerifyOATHForUser', 'oathauth-verify-user' );
35        $this->userRepo = $userRepo;
36        $this->userFactory = $userFactory;
37    }
38
39    /**
40     * @inheritDoc
41     */
42    protected function getGroupName() {
43        return 'users';
44    }
45
46    public function doesWrites() {
47        return true;
48    }
49
50    /**
51     * @return string
52     */
53    protected function getLoginSecurityLevel() {
54        return $this->getName();
55    }
56
57    /**
58     * @param HTMLForm $form
59     */
60    public function alterForm( HTMLForm $form ) {
61        $form->setMessagePrefix( 'oathauth' );
62        $form->getOutput()->setPageTitleMsg( $this->msg( 'oathauth-verify-for-user' ) );
63    }
64
65    /**
66     * @return string
67     */
68    protected function getDisplayFormat() {
69        return 'ooui';
70    }
71
72    /**
73     * @return bool
74     */
75    public function requiresUnblock() {
76        return true;
77    }
78
79    /**
80     * @param string $par
81     */
82    public function execute( $par ) {
83        $this->getOutput()->disallowUserJs();
84        parent::execute( $par );
85    }
86
87    /**
88     * @return array[]
89     */
90    protected function getFormFields() {
91        return [
92            'user' => [
93                'type' => 'user',
94                'default' => '',
95                'label-message' => 'oathauth-enteruser',
96                'name' => 'user',
97                'required' => true,
98            ],
99            'reason' => [
100                'type' => 'text',
101                'default' => '',
102                'label-message' => 'oathauth-enterverifyreason',
103                'name' => 'reason',
104                'required' => true,
105            ],
106        ];
107    }
108
109    /**
110     * @param array $formData
111     * @return array|true
112     * @throws ConfigException
113     * @throws MWException
114     */
115    public function onSubmit( array $formData ) {
116        $this->targetUser = $formData['user'];
117        $user = $this->userFactory->newFromName( $this->targetUser );
118        if ( !$user || $user->getId() === 0 ) {
119            return [ 'oathauth-user-not-found' ];
120        }
121        $oathUser = $this->userRepo->findByUser( $user );
122
123        $this->enabledStatus = $oathUser->isTwoFactorAuthEnabled()
124            ? self::OATHAUTH_IS_ENABLED
125            : self::OATHAUTH_NOT_ENABLED;
126
127        // messages used: logentry-oath-verify, log-action-oath-verify
128        $logEntry = new ManualLogEntry( 'oath', 'verify' );
129        $logEntry->setPerformer( $this->getUser() );
130        $logEntry->setTarget( $user->getUserPage() );
131        $logEntry->setComment( $formData['reason'] );
132        $logEntry->insert();
133
134        LoggerFactory::getInstance( 'authentication' )->info(
135            'OATHAuth status checked for {usertarget} by {user} from {clientip}', [
136                'user' => $this->getUser()->getName(),
137                'usertarget' => $this->targetUser,
138                'clientip' => $this->getRequest()->getIP(),
139            ]
140        );
141
142        return true;
143    }
144
145    /**
146     * @throws MWException
147     */
148    public function onSuccess() {
149        switch ( $this->enabledStatus ) {
150            case self::OATHAUTH_IS_ENABLED:
151                $msg = 'oathauth-verify-enabled';
152                break;
153            case self::OATHAUTH_NOT_ENABLED:
154                $msg = 'oathauth-verify-disabled';
155                break;
156            default:
157                throw new MWException(
158                    'Verification was successful but status is unknown'
159                );
160        }
161
162        $out = $this->getOutput();
163        $out->addBacklinkSubtitle( $this->getPageTitle() );
164        $out->addWikiMsg( $msg, $this->targetUser );
165    }
166
167}