Completed
Branch master (1b8556)
by
unknown
26:56
created

AuthManagerAuthPlugin   B

Complexity

Total Complexity 42

Size/Duplication

Total Lines 192
Duplicated Lines 21.88 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 42
loc 192
rs 8.295
wmc 42
lcom 1
cbo 9

23 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A userExists() 0 3 1
B authenticate() 16 26 6
A modifyUITemplate() 0 3 1
A setDomain() 0 3 1
A getDomain() 0 7 2
A validDomain() 0 4 2
A updateUser() 0 4 1
A autoCreate() 0 3 1
A allowPropChange() 0 3 1
A allowPasswordChange() 0 10 3
A allowSetLocalPassword() 0 4 1
B setPassword() 10 25 6
A updateExternalDB() 0 5 1
A updateExternalDBGroups() 0 4 1
A canCreateAccounts() 0 3 1
B addUser() 16 31 6
A strict() 0 4 1
A strictUserAuth() 0 4 1
A initUser() 0 3 1
A getCanonicalName() 0 4 1
A getUserInstance() 0 3 1
A domainList() 0 3 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like AuthManagerAuthPlugin often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AuthManagerAuthPlugin, and based on these observations, apply Extract Interface, too.

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
 * @file
19
 */
20
21
namespace MediaWiki\Auth;
22
23
use User;
24
25
/**
26
 * Backwards-compatibility wrapper for AuthManager via $wgAuth
27
 * @since 1.27
28
 * @deprecated since 1.27
29
 */
30
class AuthManagerAuthPlugin extends \AuthPlugin {
0 ignored issues
show
Deprecated Code introduced by
The class AuthPlugin has been deprecated with message: since 1.27

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
31
	/** @var string|null */
32
	protected $domain = null;
33
34
	/** @var \\Psr\\Log\\LoggerInterface */
35
	protected $logger = null;
36
37
	public function __construct() {
38
		$this->logger = \MediaWiki\Logger\LoggerFactory::getInstance( 'authentication' );
0 ignored issues
show
Documentation Bug introduced by
It seems like \MediaWiki\Logger\Logger...tance('authentication') of type object<Psr\Log\LoggerInterface> is incompatible with the declared type object<\Psr\\Log\\LoggerInterface> of property $logger.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
39
	}
40
41
	public function userExists( $name ) {
42
		return AuthManager::singleton()->userExists( $name );
43
	}
44
45
	public function authenticate( $username, $password ) {
46
		$data = [
47
			'username' => $username,
48
			'password' => $password,
49
		];
50 View Code Duplication
		if ( $this->domain !== null && $this->domain !== '' ) {
51
			$data['domain'] = $this->domain;
52
		}
53
		$reqs = AuthManager::singleton()->getAuthenticationRequests( AuthManager::ACTION_LOGIN );
54
		$reqs = AuthenticationRequest::loadRequestsFromSubmission( $reqs, $data );
55
56
		$res = AuthManager::singleton()->beginAuthentication( $reqs, 'null:' );
57 View Code Duplication
		switch ( $res->status ) {
58
			case AuthenticationResponse::PASS:
59
				return true;
60
			case AuthenticationResponse::FAIL:
61
				// Hope it's not a PreAuthenticationProvider that failed...
62
				$msg = $res->message instanceof \Message ? $res->message : new \Message( $res->message );
63
				$this->logger->info( __METHOD__ . ': Authentication failed: ' . $msg->plain() );
64
				return false;
65
			default:
66
				throw new \BadMethodCallException(
67
					'AuthManager does not support such simplified authentication'
68
				);
69
		}
70
	}
71
72
	public function modifyUITemplate( &$template, &$type ) {
73
		// AuthManager does not support direct UI screwing-around-with
74
	}
75
76
	public function setDomain( $domain ) {
77
		$this->domain = $domain;
78
	}
79
80
	public function getDomain() {
81
		if ( isset( $this->domain ) ) {
82
			return $this->domain;
83
		} else {
84
			return 'invaliddomain';
85
		}
86
	}
87
88
	public function validDomain( $domain ) {
89
		$domainList = $this->domainList();
90
		return $domainList ? in_array( $domain, $domainList, true ) : $domain === '';
91
	}
92
93
	public function updateUser( &$user ) {
94
		\Hooks::run( 'UserLoggedIn', [ $user ] );
95
		return true;
96
	}
97
98
	public function autoCreate() {
99
		return true;
100
	}
101
102
	public function allowPropChange( $prop = '' ) {
103
		return AuthManager::singleton()->allowsPropertyChange( $prop );
104
	}
105
106
	public function allowPasswordChange() {
107
		$reqs = AuthManager::singleton()->getAuthenticationRequests( AuthManager::ACTION_CHANGE );
108
		foreach ( $reqs as $req ) {
109
			if ( $req instanceof PasswordAuthenticationRequest ) {
110
				return true;
111
			}
112
		}
113
114
		return false;
115
	}
116
117
	public function allowSetLocalPassword() {
118
		// There should be a PrimaryAuthenticationProvider that does this, if necessary
119
		return false;
120
	}
121
122
	public function setPassword( $user, $password ) {
123
		$data = [
124
			'username' => $user->getName(),
125
			'password' => $password,
126
		];
127 View Code Duplication
		if ( $this->domain !== null && $this->domain !== '' ) {
128
			$data['domain'] = $this->domain;
129
		}
130
		$reqs = AuthManager::singleton()->getAuthenticationRequests( AuthManager::ACTION_CHANGE );
131
		$reqs = AuthenticationRequest::loadRequestsFromSubmission( $reqs, $data );
132
		foreach ( $reqs as $req ) {
133
			$status = AuthManager::singleton()->allowsAuthenticationDataChange( $req );
134 View Code Duplication
			if ( !$status->isOk() ) {
135
				$this->logger->info( __METHOD__ . ': Password change rejected: {reason}', [
136
					'username' => $data['username'],
137
					'reason' => $status->getWikiText( null, null, 'en' ),
138
				] );
139
				return false;
140
			}
141
		}
142
		foreach ( $reqs as $req ) {
143
			AuthManager::singleton()->changeAuthenticationData( $req );
144
		}
145
		return true;
146
	}
147
148
	public function updateExternalDB( $user ) {
149
		// This fires the necessary hook
150
		$user->saveSettings();
151
		return true;
152
	}
153
154
	public function updateExternalDBGroups( $user, $addgroups, $delgroups = [] ) {
155
		\Hooks::run( 'UserGroupsChanged', [ $user, $addgroups, $delgroups ] );
156
		return true;
157
	}
158
159
	public function canCreateAccounts() {
160
		return AuthManager::singleton()->canCreateAccounts();
161
	}
162
163
	public function addUser( $user, $password, $email = '', $realname = '' ) {
164
		global $wgUser;
165
166
		$data = [
167
			'username' => $user->getName(),
168
			'password' => $password,
169
			'retype' => $password,
170
			'email' => $email,
171
			'realname' => $realname,
172
		];
173 View Code Duplication
		if ( $this->domain !== null && $this->domain !== '' ) {
174
			$data['domain'] = $this->domain;
175
		}
176
		$reqs = AuthManager::singleton()->getAuthenticationRequests( AuthManager::ACTION_CREATE );
177
		$reqs = AuthenticationRequest::loadRequestsFromSubmission( $reqs, $data );
178
179
		$res = AuthManager::singleton()->beginAccountCreation( $wgUser, $reqs, 'null:' );
180 View Code Duplication
		switch ( $res->status ) {
181
			case AuthenticationResponse::PASS:
182
				return true;
183
			case AuthenticationResponse::FAIL:
184
				// Hope it's not a PreAuthenticationProvider that failed...
185
				$msg = $res->message instanceof \Message ? $res->message : new \Message( $res->message );
186
				$this->logger->info( __METHOD__ . ': Authentication failed: ' . $msg->plain() );
187
				return false;
188
			default:
189
				throw new \BadMethodCallException(
190
					'AuthManager does not support such simplified account creation'
191
				);
192
		}
193
	}
194
195
	public function strict() {
196
		// There should be a PrimaryAuthenticationProvider that does this, if necessary
197
		return true;
198
	}
199
200
	public function strictUserAuth( $username ) {
201
		// There should be a PrimaryAuthenticationProvider that does this, if necessary
202
		return true;
203
	}
204
205
	public function initUser( &$user, $autocreate = false ) {
206
		\Hooks::run( 'LocalUserCreated', [ $user, $autocreate ] );
207
	}
208
209
	public function getCanonicalName( $username ) {
210
		// AuthManager doesn't support restrictions beyond MediaWiki's
211
		return $username;
212
	}
213
214
	public function getUserInstance( User &$user ) {
215
		return new AuthManagerAuthPluginUser( $user );
0 ignored issues
show
Deprecated Code introduced by
The class MediaWiki\Auth\AuthManagerAuthPluginUser has been deprecated with message: since 1.27

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
216
	}
217
218
	public function domainList() {
219
		return [];
220
	}
221
}
222
223
/**
224
 * @since 1.27
225
 * @deprecated since 1.27
226
 */
227
class AuthManagerAuthPluginUser extends \AuthPluginUser {
0 ignored issues
show
Deprecated Code introduced by
The class AuthPluginUser has been deprecated with message: since 1.27

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
228
	/** @var User */
229
	private $user;
230
231
	function __construct( $user ) {
232
		$this->user = $user;
233
	}
234
235
	public function getId() {
236
		return $this->user->getId();
237
	}
238
239
	public function isLocked() {
240
		return $this->user->isLocked();
241
	}
242
243
	public function isHidden() {
244
		return $this->user->isHidden();
245
	}
246
247
	public function resetAuthToken() {
248
		\MediaWiki\Session\SessionManager::singleton()->invalidateSessionsForUser( $this->user );
249
		return true;
250
	}
251
}
252