19
19
20
20
namespace MediaWiki \Extension \AuthManagerOAuth ;
21
21
22
+ use League \OAuth2 \Client \Provider \GenericProvider ;
23
+ use MediaWiki \Auth \AuthenticationRequest ;
24
+ use MediaWiki \Auth \AuthenticationResponse ;
22
25
use MediaWiki \MediaWikiServices ;
23
26
24
27
class AuthManagerOAuthPrimaryAuthenticationProvider extends \MediaWiki \Auth \AbstractPrimaryAuthenticationProvider {
@@ -31,7 +34,9 @@ class AuthManagerOAuthPrimaryAuthenticationProvider extends \MediaWiki\Auth\Abst
31
34
*/
32
35
public function getAuthenticationRequests ( $ action , array $ options ) {
33
36
wfDebugLog ( 'AuthManagerOAuth getAuthenticationRequests ' , var_export ( $ action , true ) );
34
- if ( $ action === \MediaWiki \Auth \AuthManager::ACTION_LOGIN || $ action === \MediaWiki \Auth \AuthManager::ACTION_CREATE || $ action === \MediaWiki \Auth \AuthManager::ACTION_LINK ) {
37
+ if ( $ action === \MediaWiki \Auth \AuthManager::ACTION_LOGIN
38
+ || $ action === \MediaWiki \Auth \AuthManager::ACTION_CREATE
39
+ || $ action === \MediaWiki \Auth \AuthManager::ACTION_LINK ) {
35
40
$ config = MediaWikiServices::getInstance ()->getConfigFactory ()->makeConfig ( 'authmanageroauth ' );
36
41
$ reqs = [];
37
42
foreach ( $ config ->get ( 'AuthManagerOAuthConfig ' ) as $ amoa_provider => $ provider ) {
@@ -70,10 +75,11 @@ public function testUserExists( $username, $flags = User::READ_NORMAL ) {
70
75
/**
71
76
* @inheritDoc
72
77
*/
73
- public function providerAllowsAuthenticationDataChange ( \ MediaWiki \ Auth \ AuthenticationRequest $ req , $ checkData = true ) {
78
+ public function providerAllowsAuthenticationDataChange ( AuthenticationRequest $ req , $ checkData = true ) {
74
79
wfDebugLog ( 'AuthManagerOAuth providerAllowsAuthenticationDataChange ' , var_export ( $ req , true ) );
75
- if ( get_class ( $ req ) === UnlinkOAuthAccountRequest::class &&
76
- ( $ req ->action === \MediaWiki \Auth \AuthManager::ACTION_REMOVE || $ req ->action === \MediaWiki \Auth \AuthManager::ACTION_CHANGE ) ) {
80
+ if ( get_class ( $ req ) === UnlinkOAuthAccountRequest::class
81
+ && ( $ req ->action === \MediaWiki \Auth \AuthManager::ACTION_REMOVE
82
+ || $ req ->action === \MediaWiki \Auth \AuthManager::ACTION_CHANGE ) ) {
77
83
return \StatusValue::newGood ();
78
84
}
79
85
return \StatusValue::newGood ( 'ignored ' );
@@ -82,10 +88,11 @@ public function providerAllowsAuthenticationDataChange( \MediaWiki\Auth\Authenti
82
88
/**
83
89
* @inheritDoc
84
90
*/
85
- public function providerChangeAuthenticationData ( \ MediaWiki \ Auth \ AuthenticationRequest $ req ) {
91
+ public function providerChangeAuthenticationData ( AuthenticationRequest $ req ) {
86
92
wfDebugLog ( 'AuthManagerOAuth providerChangeAuthenticationData ' , var_export ( $ req , true ) );
87
- if ( get_class ( $ req ) === UnlinkOAuthAccountRequest::class &&
88
- ( $ req ->action === \MediaWiki \Auth \AuthManager::ACTION_REMOVE || $ req ->action === \MediaWiki \Auth \AuthManager::ACTION_CHANGE ) ) {
93
+ if ( get_class ( $ req ) === UnlinkOAuthAccountRequest::class
94
+ && ( $ req ->action === \MediaWiki \Auth \AuthManager::ACTION_REMOVE
95
+ || $ req ->action === \MediaWiki \Auth \AuthManager::ACTION_CHANGE ) ) {
89
96
$ user = \User::newFromName ( $ req ->username );
90
97
$ lb = MediaWikiServices::getInstance ()->getDBLoadBalancer ();
91
98
$ dbr = $ lb ->getConnectionRef ( DB_PRIMARY );
@@ -112,23 +119,30 @@ public function accountCreationType() {
112
119
/**
113
120
* This starts primary authentication/creation/linking by redirecting to the OAuth provider.
114
121
* @param array $reqs The original requests.
115
- * @return \MediaWiki\Auth\ AuthenticationResponse the response for redirecting or abstaining.
122
+ * @return AuthenticationResponse the response for redirecting or abstaining.
116
123
*/
117
124
private function beginPrimary ( array $ reqs ) {
118
125
wfDebugLog ( 'AuthManagerOAuth beginPrimary* ' , var_export ( $ reqs , true ) );
119
- $ req = \ MediaWiki \ Auth \ AuthenticationRequest::getRequestByClass ( $ reqs , ChooseOAuthProviderRequest::class );
126
+ $ req = AuthenticationRequest::getRequestByClass ( $ reqs , ChooseOAuthProviderRequest::class );
120
127
if ( $ req !== null ) {
121
128
$ config = MediaWikiServices::getInstance ()->getConfigFactory ()->makeConfig ( 'authmanageroauth ' );
122
- $ provider = new \ League \ OAuth2 \ Client \ Provider \ GenericProvider ( $ config ->get ( 'AuthManagerOAuthConfig ' )[$ req ->amoa_provider ] );
129
+ $ provider = new GenericProvider ( $ config ->get ( 'AuthManagerOAuthConfig ' )[$ req ->amoa_provider ] );
123
130
$ authorizationUrl = $ provider ->getAuthorizationUrl ( [
124
131
'redirect_uri ' => $ req ->returnToUrl
125
132
] );
126
133
127
- $ this ->manager ->setAuthenticationSessionData ( self ::AUTHENTICATION_SESSION_DATA_STATE , $ provider ->getState () );
134
+ $ this ->manager ->setAuthenticationSessionData (
135
+ self ::AUTHENTICATION_SESSION_DATA_STATE ,
136
+ $ provider ->getState ()
137
+ );
128
138
129
- return \MediaWiki \Auth \AuthenticationResponse::newRedirect ( [ new OAuthProviderAuthenticationRequest ( $ req ->amoa_provider ) ], $ authorizationUrl , null );
139
+ return AuthenticationResponse::newRedirect (
140
+ [ new OAuthProviderAuthenticationRequest ( $ req ->amoa_provider ) ],
141
+ $ authorizationUrl ,
142
+ null
143
+ );
130
144
} else {
131
- return \ MediaWiki \ Auth \ AuthenticationResponse::newAbstain ();
145
+ return AuthenticationResponse::newAbstain ();
132
146
}
133
147
}
134
148
@@ -157,19 +171,21 @@ public function beginPrimaryAccountLink( $user, array $reqs ) {
157
171
}
158
172
159
173
/**
160
- * Convert the response of an OAuth redirect to the identity it represents for further use. This asks the OAuth provider to verify the the login and gets the remote username and id.
174
+ * Convert the response of an OAuth redirect to the identity it represents for further use.
175
+ * This asks the OAuth provider to verify the the login and gets the remote username and id.
161
176
* @param OAuthProviderAuthenticationRequest $req
162
177
* @return OAuthIdentityRequest
163
178
*/
164
179
private function convertOAuthProviderAuthenticationRequestToOAuthIdentityRequest ( $ req ) {
165
180
$ config = MediaWikiServices::getInstance ()->getConfigFactory ()->makeConfig ( 'authmanageroauth ' );
166
- $ provider = new \ League \ OAuth2 \ Client \ Provider \ GenericProvider ( $ config ->get ( 'AuthManagerOAuthConfig ' )[$ req ->amoa_provider ] );
181
+ $ provider = new GenericProvider ( $ config ->get ( 'AuthManagerOAuthConfig ' )[$ req ->amoa_provider ] );
167
182
try {
168
- // TODO do we even need this authentication data or can we just store this in the authentication request. ensure again that both of it can't be manipulated
183
+ // TODO do we even need this authentication data or can we just store this in the authentication request.
184
+ // ensure again that both of it can't be manipulated
169
185
$ state = $ this ->manager ->getAuthenticationSessionData ( self ::AUTHENTICATION_SESSION_DATA_STATE );
170
186
$ this ->manager ->removeAuthenticationSessionData ( self ::AUTHENTICATION_SESSION_DATA_STATE );
171
187
if ( ( !$ state ) || $ state !== $ req ->state ) {
172
- return \ MediaWiki \ Auth \ AuthenticationResponse::newFail ( wfMessage ( 'authmanageroauth-state-mismatch ' ) );
188
+ return AuthenticationResponse::newFail ( wfMessage ( 'authmanageroauth-state-mismatch ' ) );
173
189
}
174
190
175
191
$ accessToken = $ provider ->getAccessToken ( 'authorization_code ' , [
@@ -178,15 +194,20 @@ private function convertOAuthProviderAuthenticationRequestToOAuthIdentityRequest
178
194
179
195
$ resourceOwner = $ provider ->getResourceOwner ( $ accessToken );
180
196
181
- $ req = new OAuthIdentityRequest ( $ req ->amoa_provider , $ resourceOwner ->getId (), $ resourceOwner ->toArray ()['login ' ] ); // TODO FIXME provider dependent path
197
+ // TODO FIXME provider dependent path
198
+ $ req = new OAuthIdentityRequest (
199
+ $ req ->amoa_provider ,
200
+ strval ( $ resourceOwner ->getId () ),
201
+ $ resourceOwner ->toArray ()['login ' ]
202
+ );
182
203
183
- $ response = \ MediaWiki \ Auth \ AuthenticationResponse::newPass ();
204
+ $ response = AuthenticationResponse::newPass ();
184
205
$ response ->createRequest = $ req ;
185
206
$ response ->linkRequest = $ req ;
186
207
$ response ->loginRequest = $ req ;
187
208
return $ response ;
188
209
} catch ( \League \OAuth2 \Client \Provider \Exception \IdentityProviderException $ e ) {
189
- return \ MediaWiki \ Auth \ AuthenticationResponse::newFail ( wfMessage ( 'authmanageroauth-error ' , $ e ->getMessage () ) );
210
+ return AuthenticationResponse::newFail ( wfMessage ( 'authmanageroauth-error ' , $ e ->getMessage () ) );
190
211
}
191
212
}
192
213
@@ -195,11 +216,11 @@ private function convertOAuthProviderAuthenticationRequestToOAuthIdentityRequest
195
216
*/
196
217
public function continuePrimaryAccountCreation ( $ user , $ creator , array $ reqs ) {
197
218
wfDebugLog ( 'AuthManagerOAuth continuePrimaryAccountCreation ' , var_export ( $ reqs , true ) );
198
- $ req = \ MediaWiki \ Auth \ AuthenticationRequest::getRequestByClass ( $ reqs , OAuthProviderAuthenticationRequest::class );
219
+ $ req = AuthenticationRequest::getRequestByClass ( $ reqs , OAuthProviderAuthenticationRequest::class );
199
220
if ( $ req !== null ) {
200
221
return $ this ->convertOAuthProviderAuthenticationRequestToOAuthIdentityRequest ( $ req );
201
222
} else {
202
- return \ MediaWiki \ Auth \ AuthenticationResponse::newAbstain ();
223
+ return AuthenticationResponse::newAbstain ();
203
224
}
204
225
}
205
226
@@ -209,28 +230,37 @@ public function continuePrimaryAccountCreation( $user, $creator, array $reqs ) {
209
230
public function continuePrimaryAuthentication ( array $ reqs ) {
210
231
wfDebugLog ( 'AuthManagerOAuth continuePrimaryAuthentication ' , var_export ( $ reqs , true ) );
211
232
212
- $ identity_req = \MediaWiki \Auth \AuthenticationRequest::getRequestByClass ( $ reqs , OAuthIdentityRequest::class );
213
- if ( $ identity_req !== null ) { // Already authenticated with OAuth provider
214
- $ choose_local_account_req = \MediaWiki \Auth \AuthenticationRequest::getRequestByClass ( $ reqs , ChooseLocalAccountRequest::class );
233
+ $ identity_req = AuthenticationRequest::getRequestByClass ( $ reqs , OAuthIdentityRequest::class );
234
+ if ( $ identity_req !== null ) {
235
+ // Already authenticated with OAuth provider
236
+
237
+ $ choose_local_account_req = AuthenticationRequest::getRequestByClass (
238
+ $ reqs ,
239
+ ChooseLocalAccountRequest::class
240
+ );
215
241
if ( $ choose_local_account_req !== null ) {
216
- return \ MediaWiki \ Auth \ AuthenticationResponse::newPass ( $ choose_local_account_req ->username );
242
+ return AuthenticationResponse::newPass ( $ choose_local_account_req ->username );
217
243
}
218
244
219
- $ choose_local_username_req = \MediaWiki \Auth \AuthenticationRequest::getRequestByClass ( $ reqs , LocalUsernameInputRequest::class );
245
+ $ choose_local_username_req = AuthenticationRequest::getRequestByClass (
246
+ $ reqs ,
247
+ LocalUsernameInputRequest::class
248
+ );
220
249
if ( $ choose_local_username_req !== null ) {
221
250
$ user = \User::newFromName ( $ choose_local_username_req ->local_username );
222
- if ( !$ user ->isRegistered () ) { // TODO FIXME query on primary race condition but that's just how it is https://phabricator.wikimedia.org/T138678#3911381
223
- return \MediaWiki \Auth \AuthenticationResponse::newPass ( $ choose_local_username_req ->local_username );
251
+ // TODO FIXME query on primary race condition https://phabricator.wikimedia.org/T138678#3911381
252
+ if ( !$ user ->isRegistered () ) {
253
+ return AuthenticationResponse::newPass ( $ choose_local_username_req ->local_username );
224
254
} else {
225
- return \ MediaWiki \ Auth \ AuthenticationResponse::newFail ( wfMessage ( 'authmanageroauth-account-already-exists ' ) );
255
+ return AuthenticationResponse::newFail ( wfMessage ( 'authmanageroauth-account-already-exists ' ) );
226
256
}
227
257
}
228
258
}
229
259
230
- $ req = \ MediaWiki \ Auth \ AuthenticationRequest::getRequestByClass ( $ reqs , OAuthProviderAuthenticationRequest::class );
260
+ $ req = AuthenticationRequest::getRequestByClass ( $ reqs , OAuthProviderAuthenticationRequest::class );
231
261
if ( $ req !== null ) {
232
262
$ resp = $ this ->convertOAuthProviderAuthenticationRequestToOAuthIdentityRequest ( $ req );
233
- if ( $ resp ->status !== \ MediaWiki \ Auth \ AuthenticationResponse::PASS ) {
263
+ if ( $ resp ->status !== AuthenticationResponse::PASS ) {
234
264
return $ resp ;
235
265
}
236
266
@@ -256,24 +286,24 @@ public function continuePrimaryAuthentication( array $reqs ) {
256
286
] );
257
287
if ( count ( $ reqs ) === 2 ) {
258
288
// There are no previous linked accounts
259
- return \ MediaWiki \ Auth \ AuthenticationResponse::newUI ( $ reqs , wfMessage ( 'authmanageroauth-choose-username ' ) );
289
+ return AuthenticationResponse::newUI ( $ reqs , wfMessage ( 'authmanageroauth-choose-username ' ) );
260
290
} else {
261
291
// There are already accounts linked
262
- return \ MediaWiki \ Auth \ AuthenticationResponse::newUI ( $ reqs , wfMessage ( 'authmanageroauth-choose-message ' ) );
292
+ return AuthenticationResponse::newUI ( $ reqs , wfMessage ( 'authmanageroauth-choose-message ' ) );
263
293
}
264
294
}
265
- return \ MediaWiki \ Auth \ AuthenticationResponse::newAbstain ();
295
+ return AuthenticationResponse::newAbstain ();
266
296
}
267
297
268
298
/**
269
299
* @inheritDoc
270
300
*/
271
301
public function continuePrimaryAccountLink ( $ user , array $ reqs ) {
272
302
wfDebugLog ( 'AuthManagerOAuth continuePrimaryAccountLink ' , var_export ( $ reqs , true ) );
273
- $ req = \ MediaWiki \ Auth \ AuthenticationRequest::getRequestByClass ( $ reqs , OAuthProviderAuthenticationRequest::class );
303
+ $ req = AuthenticationRequest::getRequestByClass ( $ reqs , OAuthProviderAuthenticationRequest::class );
274
304
if ( $ req !== null ) {
275
305
$ resp = $ this ->convertOAuthProviderAuthenticationRequestToOAuthIdentityRequest ( $ req );
276
- if ( $ resp ->status !== \ MediaWiki \ Auth \ AuthenticationResponse::PASS ) {
306
+ if ( $ resp ->status !== AuthenticationResponse::PASS ) {
277
307
return $ resp ;
278
308
}
279
309
@@ -295,7 +325,7 @@ public function continuePrimaryAccountLink( $user, array $reqs ) {
295
325
return $ resp ;
296
326
} else {
297
327
// TODO FIXME maybe we can put this in the common method so this is even less duplication
298
- return \ MediaWiki \ Auth \ AuthenticationResponse::newAbstain ();
328
+ return AuthenticationResponse::newAbstain ();
299
329
}
300
330
}
301
331
@@ -321,7 +351,7 @@ public function autoCreatedAccount( $user, $source ) {
321
351
/**
322
352
* @inheritDoc
323
353
*/
324
- public function finishAccountCreation ( $ user , $ creator , \ MediaWiki \ Auth \ AuthenticationResponse $ response ) {
354
+ public function finishAccountCreation ( $ user , $ creator , AuthenticationResponse $ response ) {
325
355
wfDebugLog ( 'AuthManagerOAuth finishAccountCreation ' , var_export ( $ response , true ) );
326
356
$ req = $ response ->createRequest ;
327
357
$ lb = MediaWikiServices::getInstance ()->getDBLoadBalancer ();
0 commit comments