Switch to new hook handler format

* Turn HSTSPreloadLookup into a real service, per @todo
* Convert Hooks into a non-static class, take lookup as an argument
* Update tests for new calling style

== Test plan ==
* CI/tests pass
* Use Special:ExpandTemplates with a preloaded domain and localhost,
  observe preloaded link changes, localhost stays http

Bug: T271027
Change-Id: I0196350e85c09eedfba4dbf1dab81f9a757b2a12
This commit is contained in:
Kunal Mehta 2022-06-05 12:06:20 -04:00
parent 62898355d3
commit 0509d34225
6 changed files with 53 additions and 22 deletions

View file

@ -16,8 +16,19 @@
"MessagesDirs": { "MessagesDirs": {
"SecureLinkFixer": "i18n" "SecureLinkFixer": "i18n"
}, },
"Hooks": { "HookHandlers": {
"LinkerMakeExternalLink": "MediaWiki\\SecureLinkFixer\\Hooks::onLinkerMakeExternalLink" "main": {
"class": "MediaWiki\\SecureLinkFixer\\Hooks",
"services": [
"HSTSPreloadLookup"
]
}
}, },
"Hooks": {
"LinkerMakeExternalLink": "main"
},
"ServiceWiringFiles": [
"includes/ServiceWiring.php"
],
"manifest_version": 2 "manifest_version": 2
} }

View file

@ -25,20 +25,6 @@ class HSTSPreloadLookup {
*/ */
private $domains; private $domains;
/**
* @todo turn into proper MWServices thing
* @codeCoverageIgnore
* @return HSTSPreloadLookup
*/
public static function getInstance() {
static $instance;
if ( !$instance ) {
$instance = new self( require __DIR__ . '/../domains.php' );
}
return $instance;
}
/** /**
* @param array $domains * @param array $domains
*/ */

View file

@ -18,16 +18,35 @@
namespace MediaWiki\SecureLinkFixer; namespace MediaWiki\SecureLinkFixer;
class Hooks { use MediaWiki\Hook\LinkerMakeExternalLinkHook;
class Hooks implements LinkerMakeExternalLinkHook {
/** @var HSTSPreloadLookup */
private $lookup;
/**
* @param HSTSPreloadLookup $lookup
*/
public function __construct( HSTSPreloadLookup $lookup ) {
$this->lookup = $lookup;
}
/** /**
* Hook: LinkerMakeExternalLink * Hook: LinkerMakeExternalLink
* *
* Changes the scheme of the URL to HTTPS if necessary * Changes the scheme of the URL to HTTPS if necessary
* *
* @param string &$url * @param string &$url Link URL
* @param string &$text Link text
* @param string &$link New link HTML (if returning false)
* @param string[] &$attribs Attributes to be applied
* @param string $linkType External link type
* @return bool|void True or no return value to continue or false to abort
*/ */
public static function onLinkerMakeExternalLink( &$url ) { public function onLinkerMakeExternalLink(
&$url, &$text, &$link, &$attribs, $linkType
) {
if ( strpos( $url, 'https://' ) === 0 ) { if ( strpos( $url, 'https://' ) === 0 ) {
// Already HTTPS // Already HTTPS
return; return;
@ -43,7 +62,7 @@ class Hooks {
return; return;
} }
if ( HSTSPreloadLookup::getInstance()->isPreloaded( $parsed['host'] ) ) { if ( $this->lookup->isPreloaded( $parsed['host'] ) ) {
$parsed['scheme'] = 'https'; $parsed['scheme'] = 'https';
$parsed['delimiter'] = '://'; $parsed['delimiter'] = '://';
$url = wfAssembleUrl( $parsed ); $url = wfAssembleUrl( $parsed );

View file

@ -0,0 +1,11 @@
<?php
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (C) 2022 Kunal Mehta <legoktm@debian.org>
namespace MediaWiki\SecureLinkFixer;
return [
'HSTSPreloadLookup' => static function () {
return new HSTSPreloadLookup( require __DIR__ . '/../domains.php' );
}
];

View file

@ -19,6 +19,7 @@
namespace MediaWiki\SecureLinkFixer; namespace MediaWiki\SecureLinkFixer;
use Benchmarker; use Benchmarker;
use MediaWiki\MediaWikiServices;
use const RUN_MAINTENANCE_IF_MAIN; use const RUN_MAINTENANCE_IF_MAIN;
$IP = getenv( 'MW_INSTALL_PATH' ); $IP = getenv( 'MW_INSTALL_PATH' );
@ -40,7 +41,7 @@ class BenchLookup extends Benchmarker {
} }
public function execute() { public function execute() {
$lookup = HSTSPreloadLookup::getInstance(); $lookup = MediaWikiServices::getInstance()->getService( 'HSTSPreloadLookup' );
$domains = [ $domains = [
// Need to traverse up one domain to find it // Need to traverse up one domain to find it
'foobar.dev', 'foobar.dev',

View file

@ -30,7 +30,10 @@ class HooksTest extends MediaWikiIntegrationTestCase {
* @dataProvider provideOnLinkerMakeExternalLink * @dataProvider provideOnLinkerMakeExternalLink
*/ */
public function testOnLinkerMakeExternalLink( $input, $expected ) { public function testOnLinkerMakeExternalLink( $input, $expected ) {
Hooks::onLinkerMakeExternalLink( $input ); $hooks = new Hooks( $this->getServiceContainer()->getService( 'HSTSPreloadLookup' ) );
$dummy = '';
$dummy2 = [];
$hooks->onLinkerMakeExternalLink( $input, $dummy, $dummy, $dummy2, $dummy );
$this->assertSame( $expected, $input ); $this->assertSame( $expected, $input );
} }