1<?php
2
3namespace MediaWiki\Extension\OATHAuth\Special;
4
5use ConfigException;
6use FormSpecialPage;
7use HTMLForm;
8use ManualLogEntry;
9use MediaWiki\Extension\OATHAuth\IModule;
10use MediaWiki\Extension\OATHAuth\OATHUserRepository;
11use MediaWiki\Logger\LoggerFactory;
12use MediaWiki\MediaWikiServices;
13use Message;
14use MWException;
15use User;
16use UserBlockedError;
17use UserNotLoggedIn;
18
19class DisableOATHForUser extends FormSpecialPage {
20	/** @var OATHUserRepository */
21	private $userRepo;
22
23	public function __construct() {
24		parent::__construct( 'DisableOATHForUser', 'oathauth-disable-for-user' );
25
26		$this->userRepo = MediaWikiServices::getInstance()->getService( 'OATHUserRepository' );
27	}
28
29	public function doesWrites() {
30		return true;
31	}
32
33	/**
34	 * @return string
35	 */
36	protected function getLoginSecurityLevel() {
37		return $this->getName();
38	}
39
40	/**
41	 * Set the page title and add JavaScript RL modules
42	 *
43	 * @param HTMLForm $form
44	 */
45	public function alterForm( HTMLForm $form ) {
46		$form->setMessagePrefix( 'oathauth' );
47		$form->setWrapperLegendMsg( 'oathauth-disable-header' );
48		$form->setPreText( $this->msg( 'oathauth-disable-intro' )->parse() );
49		$form->getOutput()->setPageTitle( $this->msg( 'oathauth-disable-for-user' ) );
50	}
51
52	/**
53	 * @return string
54	 */
55	protected function getDisplayFormat() {
56		return 'ooui';
57	}
58
59	/**
60	 * @return bool
61	 */
62	public function requiresUnblock() {
63		return false;
64	}
65
66	/**
67	 * @param User $user
68	 * @throws UserBlockedError
69	 * @throws UserNotLoggedIn
70	 */
71	protected function checkExecutePermissions( User $user ) {
72		parent::checkExecutePermissions( $user );
73
74		$this->requireLogin();
75	}
76
77	/**
78	 * @param string $par
79	 */
80	public function execute( $par ) {
81		$this->getOutput()->disallowUserJs();
82		parent::execute( $par );
83	}
84
85	/**
86	 * @return array[]
87	 */
88	protected function getFormFields() {
89		return [
90			'user' => [
91				'type' => 'user',
92				'default' => '',
93				'label-message' => 'oathauth-enteruser',
94				'name' => 'user',
95				'required' => true,
96			],
97			'reason' => [
98				'type' => 'text',
99				'default' => '',
100				'label-message' => 'oathauth-enterdisablereason',
101				'name' => 'reason',
102				'required' => true,
103			],
104		];
105	}
106
107	/**
108	 * @param array $formData
109	 * @return array|bool
110	 * @throws ConfigException
111	 * @throws MWException
112	 */
113	public function onSubmit( array $formData ) {
114		$user = User::newFromName( $formData['user'] );
115		if ( $user && $user->getId() === 0 ) {
116			return [ 'oathauth-user-not-found' ];
117		}
118		$oathUser = $this->userRepo->findByUser( $user );
119
120		if ( !( $oathUser->getModule() instanceof IModule ) ||
121			!$oathUser->getModule()->isEnabled( $oathUser ) ) {
122			return [ 'oathauth-user-not-does-not-have-oath-enabled' ];
123		}
124
125		if ( $this->getUser()->pingLimiter( 'disableoath', 0 ) ) {
126			// Arbitrary duration given here
127			return [ 'oathauth-throttled', Message::durationParam( 60 ) ];
128		}
129
130		$oathUser->disable();
131		$this->userRepo->remove( $oathUser, $this->getRequest()->getIP() );
132
133		$logEntry = new ManualLogEntry( 'oath', 'disable-other' );
134		$logEntry->setPerformer( $this->getUser() );
135		$logEntry->setTarget( $user->getUserPage() );
136		$logEntry->setComment( $formData['reason'] );
137		$logEntry->insert();
138
139		LoggerFactory::getInstance( 'authentication' )->info(
140			'OATHAuth disabled for {usertarget} by {user} from {clientip}', [
141				'user' => $this->getUser()->getName(),
142				'usertarget' => $formData['user'],
143				'clientip' => $this->getRequest()->getIP(),
144			]
145		);
146
147		return true;
148	}
149
150	public function onSuccess() {
151		$this->getOutput()->addWikiMsg( 'oathauth-disabledoath' );
152		$this->getOutput()->returnToMain();
153	}
154
155}
156