3 namespace MediaWiki\Auth
;
9 * Links third-party authentication to the user's account
11 * If the user logged into linking provider accounts that aren't linked to a
12 * local user, this provider will prompt the user to link them after a
13 * successful login or account creation.
15 * To avoid confusing behavior, this provider should be later in the
16 * configuration list than any provider that can abort the authentication
17 * process, so that it is only invoked for successful authentication.
19 class ConfirmLinkSecondaryAuthenticationProvider
extends AbstractSecondaryAuthenticationProvider
{
21 public function getAuthenticationRequests( $action, array $options ) {
25 public function beginSecondaryAuthentication( $user, array $reqs ) {
26 return $this->beginLinkAttempt( $user, 'AuthManager::authnState' );
29 public function continueSecondaryAuthentication( $user, array $reqs ) {
30 return $this->continueLinkAttempt( $user, 'AuthManager::authnState', $reqs );
33 public function beginSecondaryAccountCreation( $user, $creator, array $reqs ) {
34 return $this->beginLinkAttempt( $user, 'AuthManager::accountCreationState' );
37 public function continueSecondaryAccountCreation( $user, $creator, array $reqs ) {
38 return $this->continueLinkAttempt( $user, 'AuthManager::accountCreationState', $reqs );
42 * Begin the link attempt
44 * @param string $key Session key to look in
45 * @return AuthenticationResponse
47 protected function beginLinkAttempt( $user, $key ) {
48 $session = $this->manager
->getRequest()->getSession();
49 $state = $session->getSecret( $key );
50 if ( !is_array( $state ) ) {
51 return AuthenticationResponse
::newAbstain();
53 $maybeLink = $state['maybeLink'];
55 return AuthenticationResponse
::newAbstain();
58 $req = new ConfirmLinkAuthenticationRequest( $maybeLink );
59 return AuthenticationResponse
::newUI(
61 wfMessage( 'authprovider-confirmlink-message' )
66 * Continue the link attempt
68 * @param string $key Session key to look in
69 * @param AuthenticationRequest[] $reqs
70 * @return AuthenticationResponse
72 protected function continueLinkAttempt( $user, $key, array $reqs ) {
73 $req = ButtonAuthenticationRequest
::getRequestByName( $reqs, 'linkOk' );
75 return AuthenticationResponse
::newPass();
78 $req = AuthenticationRequest
::getRequestByClass( $reqs, ConfirmLinkAuthenticationRequest
::class );
81 return $this->beginLinkAttempt( $user, $key );
84 $session = $this->manager
->getRequest()->getSession();
85 $state = $session->getSecret( $key );
86 if ( !is_array( $state ) ) {
87 return AuthenticationResponse
::newAbstain();
91 foreach ( $state['maybeLink'] as $linkReq ) {
92 $maybeLink[$linkReq->getUniqueId()] = $linkReq;
95 return AuthenticationResponse
::newAbstain();
98 $state['maybeLink'] = [];
99 $session->setSecret( $key, $state );
103 foreach ( $req->confirmedLinkIDs
as $id ) {
104 if ( isset( $maybeLink[$id] ) ) {
105 $req = $maybeLink[$id];
106 $req->username
= $user->getName();
107 if ( !$req->action
) {
108 // Make sure the action is set, but don't override it if
109 // the provider filled it in.
110 $req->action
= AuthManager
::ACTION_CHANGE
;
112 $status = $this->manager
->allowsAuthenticationDataChange( $req );
113 $statuses[] = [ $req, $status ];
114 if ( $status->isGood() ) {
115 $this->manager
->changeAuthenticationData( $req );
122 return AuthenticationResponse
::newPass();
125 $combinedStatus = \Status
::newGood();
126 foreach ( $statuses as $data ) {
127 list( $req, $status ) = $data;
128 $descriptionInfo = $req->describeCredentials();
129 $description = wfMessage(
130 'authprovider-confirmlink-option',
131 $descriptionInfo['provider']->text(), $descriptionInfo['account']->text()
133 if ( $status->isGood() ) {
134 $combinedStatus->error( wfMessage( 'authprovider-confirmlink-success-line', $description ) );
136 $combinedStatus->error( wfMessage(
137 'authprovider-confirmlink-failure-line', $description, $status->getMessage()->text()
141 return AuthenticationResponse
::newUI(
143 new ButtonAuthenticationRequest(
144 'linkOk', wfMessage( 'ok' ), wfMessage( 'authprovider-confirmlink-ok-help' )
147 $combinedStatus->getMessage( 'authprovider-confirmlink-failed' )