Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
ContentSecurityPolicyHookHandler
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 3
156
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 onContentSecurityPolicyDefaultSource
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
72
 onContentSecurityPolicyScriptSource
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
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
21namespace MediaWiki\Extension\CentralAuth\Hooks\Handlers;
22
23use MediaWiki\Config\Config;
24use MediaWiki\Extension\CentralAuth\CentralAuthHooks;
25use MediaWiki\Hook\ContentSecurityPolicyDefaultSourceHook;
26use MediaWiki\Hook\ContentSecurityPolicyScriptSourceHook;
27use MediaWiki\WikiMap\WikiMap;
28use RequestContext;
29
30class ContentSecurityPolicyHookHandler implements
31    ContentSecurityPolicyDefaultSourceHook,
32    ContentSecurityPolicyScriptSourceHook
33{
34    /** @var Config */
35    private $config;
36
37    /**
38     * @param Config $config
39     */
40    public function __construct( Config $config ) {
41        $this->config = $config;
42    }
43
44    /**
45     * Add other domains as CSP source if auto-login is going to be attempted
46     *
47     * This is adding domains for images (and other req types), not scripts.
48     *
49     * @note We can't do $out->getCSP()->addDefaultSrc in onBeforePageDisplay,
50     * because that hook runs after the header is already outputted.
51     * @param string[] &$defaultSrc Array of allowed CSP sources.
52     * @param array $policyConfig
53     * @param int $mode
54     */
55    public function onContentSecurityPolicyDefaultSource(
56        &$defaultSrc,
57        $policyConfig,
58        $mode
59    ) {
60        $out = RequestContext::getMain()->getOutput();
61        // So possibilities:
62        // * We are doing edge login because initial login was via API and this is next request.
63        // * We are doing edge login because JS loaded Special:CentralAutoLogin/start or /checkCookies
64        //   and user is logged in on a different wiki, which eventually loads edge html.
65        if (
66            !$out->getUser()->isRegistered() ||
67                $out->getRequest()->getSessionData( 'CentralAuthDoEdgeLogin' )
68        ) {
69            foreach ( CentralAuthHooks::getAutoLoginWikis() as $wikiID ) {
70                $wiki = WikiMap::getWiki( $wikiID );
71                $url = $wiki->getCanonicalServer();
72                if ( CentralAuthHooks::isMobileDomain() ) {
73                    $url = \MobileContext::singleton()->getMobileUrl( $url );
74                }
75                $defaultSrc[] = wfParseUrl( $url )['host'];
76            }
77        }
78
79        if ( !$out->getUser()->isRegistered() && $this->config->get( 'CentralAuthLoginWiki' ) ) {
80            // For the non-js case, there is local image loaded, but it redirects to
81            // central wiki, so include it.
82            $loginWiki = WikiMap::getWiki( $this->config->get( 'CentralAuthLoginWiki' ) );
83            $url = $loginWiki->getCanonicalServer();
84            if ( CentralAuthHooks::isMobileDomain() ) {
85                $url = \MobileContext::singleton()->getMobileUrl( $url );
86            }
87            $defaultSrc[] = wfParseUrl( $url )['host'];
88        }
89    }
90
91    /**
92     * Add other domains as CSP source if auto-login is going to be attempted
93     *
94     * This is adding domains for scripts but not images.
95     *
96     * This is basically for ext.centralauth.centralautologin and corresponds
97     * to self::getCentralautologinJsData
98     *
99     * @note We can't do $out->getCSP()->addScriptSrc() in onBeforePageDisplay,
100     * because that hook runs after the header is already outputted.
101     * @param string[] &$scriptSrc Array of allowed CSP sources.
102     * @param array $policyConfig
103     * @param int $mode
104     */
105    public function onContentSecurityPolicyScriptSource(
106        &$scriptSrc,
107        $policyConfig,
108        $mode
109    ) {
110        $out = RequestContext::getMain()->getOutput();
111        if ( $this->config->get( 'CentralAuthLoginWiki' ) && !$out->getUser()->isRegistered() ) {
112            $loginWiki = WikiMap::getWiki( $this->config->get( 'CentralAuthLoginWiki' ) );
113            $scriptSrc[] = wfParseUrl( $loginWiki->getCanonicalServer() )['host'];
114        }
115    }
116}