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