Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 55 |
|
0.00% |
0 / 5 |
CRAP | |
0.00% |
0 / 1 |
ApiOATHValidate | |
0.00% |
0 / 55 |
|
0.00% |
0 / 5 |
182 | |
0.00% |
0 / 1 |
execute | |
0.00% |
0 / 38 |
|
0.00% |
0 / 1 |
90 | |||
isInternal | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
needsToken | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getAllowedParams | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 | |||
getExamplesMessages | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | /** |
3 | * This program is free software; you can redistribute it and/or modify |
4 | * it under the terms of the GNU General Public License as published by |
5 | * the Free Software Foundation; either version 2 of the License, or |
6 | * (at your option) any later version. |
7 | * |
8 | * This program is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | * GNU General Public License for more details. |
12 | * |
13 | * You should have received a copy of the GNU General Public License along |
14 | * with this program; if not, write to the Free Software Foundation, Inc., |
15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
16 | * http://www.gnu.org/copyleft/gpl.html |
17 | */ |
18 | |
19 | namespace MediaWiki\Extension\OATHAuth\Api\Module; |
20 | |
21 | use ApiBase; |
22 | use ApiResult; |
23 | use FormatJson; |
24 | use MediaWiki\Extension\OATHAuth\IModule; |
25 | use MediaWiki\Logger\LoggerFactory; |
26 | use MediaWiki\MediaWikiServices; |
27 | use Wikimedia\ParamValidator\ParamValidator; |
28 | |
29 | /** |
30 | * Validate an OATH token. |
31 | * |
32 | * @ingroup API |
33 | * @ingroup Extensions |
34 | */ |
35 | class ApiOATHValidate extends ApiBase { |
36 | public function execute() { |
37 | $this->requirePostedParameters( [ 'token', 'data' ] ); |
38 | // messages used: right-oathauth-api-all, action-oathauth-api-all, |
39 | $this->checkUserRightsAny( 'oathauth-api-all' ); |
40 | |
41 | $params = $this->extractRequestParams(); |
42 | if ( $params['user'] === null ) { |
43 | $user = $this->getUser(); |
44 | } else { |
45 | $user = MediaWikiServices::getInstance()->getUserFactory() |
46 | ->newFromName( $params['user'] ); |
47 | if ( $user === null ) { |
48 | $this->dieWithError( 'noname' ); |
49 | } |
50 | } |
51 | |
52 | // Don't increase pingLimiter, just check for limit exceeded. |
53 | if ( $user->pingLimiter( 'badoath', 0 ) ) { |
54 | $this->dieWithError( 'apierror-ratelimited' ); |
55 | } |
56 | |
57 | $result = [ |
58 | ApiResult::META_BC_BOOLS => [ 'enabled', 'valid' ], |
59 | 'enabled' => false, |
60 | 'valid' => false, |
61 | ]; |
62 | |
63 | if ( $user->isNamed() ) { |
64 | $userRepo = MediaWikiServices::getInstance()->getService( 'OATHUserRepository' ); |
65 | $authUser = $userRepo->findByUser( $user ); |
66 | if ( $authUser ) { |
67 | $module = $authUser->getModule(); |
68 | if ( $module instanceof IModule ) { |
69 | $data = []; |
70 | $decoded = FormatJson::decode( $params['data'], true ); |
71 | if ( is_array( $decoded ) ) { |
72 | $data = $decoded; |
73 | } |
74 | |
75 | $result['enabled'] = $module->isEnabled( $authUser ); |
76 | $result['valid'] = $module->verify( $authUser, $data ) !== false; |
77 | |
78 | if ( !$result['valid'] ) { |
79 | // Increase rate limit counter for failed request |
80 | $user->pingLimiter( 'badoath' ); |
81 | |
82 | LoggerFactory::getInstance( 'authentication' )->info( |
83 | 'OATHAuth user {user} failed OTP token/recovery code from {clientip}', |
84 | [ |
85 | 'user' => $user, |
86 | 'clientip' => $user->getRequest()->getIP(), |
87 | ] |
88 | ); |
89 | } |
90 | } |
91 | } |
92 | } |
93 | |
94 | $this->getResult()->addValue( null, $this->getModuleName(), $result ); |
95 | } |
96 | |
97 | /** @inheritDoc */ |
98 | public function isInternal() { |
99 | return true; |
100 | } |
101 | |
102 | /** @inheritDoc */ |
103 | public function needsToken() { |
104 | return 'csrf'; |
105 | } |
106 | |
107 | /** |
108 | * @return array |
109 | */ |
110 | public function getAllowedParams() { |
111 | return [ |
112 | 'user' => [ |
113 | ParamValidator::PARAM_TYPE => 'user', |
114 | ], |
115 | 'data' => [ |
116 | ParamValidator::PARAM_TYPE => 'string', |
117 | ParamValidator::PARAM_REQUIRED => true, |
118 | ] |
119 | ]; |
120 | } |
121 | |
122 | /** |
123 | * @return array |
124 | */ |
125 | protected function getExamplesMessages() { |
126 | return [ |
127 | 'action=oathvalidate&data={"token":"123456"}&token=123ABC' |
128 | => 'apihelp-oathvalidate-example-1', |
129 | 'action=oathvalidate&user=Example&data={"token":"123456"}&token=123ABC' |
130 | => 'apihelp-oathvalidate-example-3', |
131 | ]; |
132 | } |
133 | } |