Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialLinkAccounts
0.00% covered (danger)
0.00%
0 / 40
0.00% covered (danger)
0.00%
0 / 8
306
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getGroupName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isListed
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getRequestBlacklist
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 29
0.00% covered (danger)
0.00%
0 / 1
110
 getDefaultAction
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getAuthForm
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 success
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Specials;
4
5use LogicException;
6use MediaWiki\Auth\AuthenticationRequest;
7use MediaWiki\Auth\AuthenticationResponse;
8use MediaWiki\Auth\AuthManager;
9use MediaWiki\Exception\ErrorPageError;
10use MediaWiki\HTMLForm\HTMLForm;
11use MediaWiki\MainConfigNames;
12use MediaWiki\SpecialPage\AuthManagerSpecialPage;
13use StatusValue;
14
15/**
16 * Link/unlink external accounts to the current user.
17 *
18 * To interact with this page, account providers need to register themselves with AuthManager.
19 *
20 * @ingroup SpecialPage
21 * @ingroup Auth
22 */
23class SpecialLinkAccounts extends AuthManagerSpecialPage {
24    /** @inheritDoc */
25    protected static $allowedActions = [
26        AuthManager::ACTION_LINK, AuthManager::ACTION_LINK_CONTINUE,
27    ];
28
29    public function __construct( AuthManager $authManager ) {
30        parent::__construct( 'LinkAccounts' );
31        $this->setAuthManager( $authManager );
32    }
33
34    /** @inheritDoc */
35    protected function getGroupName() {
36        return 'login';
37    }
38
39    /** @inheritDoc */
40    public function isListed() {
41        return $this->getAuthManager()->canLinkAccounts();
42    }
43
44    /** @inheritDoc */
45    protected function getRequestBlacklist() {
46        return $this->getConfig()->get( MainConfigNames::ChangeCredentialsBlacklist );
47    }
48
49    /**
50     * @param null|string $subPage
51     * @throws ErrorPageError
52     */
53    public function execute( $subPage ) {
54        $this->setHeaders();
55        $this->loadAuth( $subPage );
56
57        if ( !$this->isActionAllowed( $this->authAction ) ) {
58            if ( $this->authAction === AuthManager::ACTION_LINK ) {
59                // looks like no linking provider is installed or willing to take this user
60                $titleMessage = $this->msg( 'cannotlink-no-provider-title' );
61                $errorMessage = $this->msg( 'cannotlink-no-provider' );
62                throw new ErrorPageError( $titleMessage, $errorMessage );
63            } else {
64                // user probably back-button-navigated into an auth session that no longer exists
65                // FIXME would be nice to show a message
66                $this->getOutput()->redirect( $this->getPageTitle()->getFullURL( '', false,
67                    PROTO_HTTPS ) );
68                return;
69            }
70        }
71
72        $this->outputHeader();
73
74        $status = $this->trySubmit();
75
76        if ( $status === false || !$status->isOK() ) {
77            $this->displayForm( $status );
78            return;
79        }
80
81        $response = $status->getValue();
82
83        switch ( $response->status ) {
84            case AuthenticationResponse::PASS:
85                $this->success();
86                break;
87            case AuthenticationResponse::FAIL:
88                $this->loadAuth( '', AuthManager::ACTION_LINK, true );
89                $this->displayForm( StatusValue::newFatal( $response->message ) );
90                break;
91            case AuthenticationResponse::REDIRECT:
92                $this->getOutput()->redirect( $response->redirectTarget );
93                break;
94            case AuthenticationResponse::UI:
95                $this->authAction = AuthManager::ACTION_LINK_CONTINUE;
96                $this->authRequests = $response->neededRequests;
97                $this->displayForm( StatusValue::newFatal( $response->message ) );
98                break;
99            default:
100                throw new LogicException( 'invalid AuthenticationResponse' );
101        }
102    }
103
104    /** @inheritDoc */
105    protected function getDefaultAction( $subPage ) {
106        return AuthManager::ACTION_LINK;
107    }
108
109    /**
110     * @param AuthenticationRequest[] $requests
111     * @param string $action AuthManager action name, should be ACTION_LINK or ACTION_LINK_CONTINUE
112     * @return HTMLForm
113     */
114    protected function getAuthForm( array $requests, $action ) {
115        $form = parent::getAuthForm( $requests, $action );
116        $form->setSubmitTextMsg( 'linkaccounts-submit' );
117        return $form;
118    }
119
120    /**
121     * Show a success message.
122     */
123    protected function success() {
124        $this->loadAuth( '', AuthManager::ACTION_LINK, true );
125        $this->displayForm( StatusValue::newFatal( $this->msg( 'linkaccounts-success-text' ) ) );
126    }
127}
128
129/** @deprecated class alias since 1.41 */
130class_alias( SpecialLinkAccounts::class, 'SpecialLinkAccounts' );