mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/CookieWarning
synced 2024-11-23 13:56:53 +00:00
Add caching functionality for IP lookup
Instead of always looking up a single IP address, even for multiple requests, cache the result of the first lookup. IP addresses usually doesn't move that fast, caching the result should therefore be reasonably ok. Change-Id: Ice78ec08ff886e77c542a75086610498eaa6c6b4
This commit is contained in:
parent
fed15fd7a5
commit
6f519c9618
|
@ -3,14 +3,19 @@
|
|||
class CookieWarningDecisions {
|
||||
private $config;
|
||||
private $geoLocation;
|
||||
private $cache;
|
||||
|
||||
const CACHE_KEY = 'cookieWarningIpLookupCache:';
|
||||
|
||||
/**
|
||||
* @param Config $config
|
||||
* @param GeoLocation $geoLocation
|
||||
* @param WANObjectCache $cache
|
||||
*/
|
||||
public function __construct( Config $config, GeoLocation $geoLocation ) {
|
||||
public function __construct( Config $config, GeoLocation $geoLocation, WANObjectCache $cache ) {
|
||||
$this->config = $config;
|
||||
$this->geoLocation = $geoLocation;
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,8 +40,6 @@ class CookieWarningDecisions {
|
|||
/**
|
||||
* Checks, if the user is in one of the configured regions.
|
||||
*
|
||||
* @TODO: This function or the function users should set the cookie or user option, if this
|
||||
* function returns false to avoid a location lookup on each request.
|
||||
* @param IContextSource $context
|
||||
* @return bool
|
||||
* @throws ConfigException
|
||||
|
@ -50,18 +53,9 @@ class CookieWarningDecisions {
|
|||
return true;
|
||||
}
|
||||
|
||||
wfDebugLog( 'CookieWarning', 'Try to locate the user\'s IP address.' );
|
||||
$located = $this->geoLocation->locate( $context->getRequest()->getIP() );
|
||||
if ( !$located ) {
|
||||
wfDebugLog( 'CookieWarning',
|
||||
'Locating the user\'s IP address failed or is' . ' configured false.' );
|
||||
$countryCode = $this->getCountryCodeFromIP( $context->getRequest()->getIP() );
|
||||
|
||||
return true;
|
||||
}
|
||||
wfDebugLog( 'CookieWarning', 'Locating the user was successful, located' . ' region: ' .
|
||||
$this->geoLocation->getCountryCode() );
|
||||
|
||||
return array_key_exists( $this->geoLocation->getCountryCode(),
|
||||
return array_key_exists( $countryCode,
|
||||
$this->config->get( 'CookieWarningForCountryCodes' ) );
|
||||
}
|
||||
|
||||
|
@ -73,4 +67,35 @@ class CookieWarningDecisions {
|
|||
return $this->config->get( 'CookieWarningGeoIPLookup' ) === 'js' &&
|
||||
is_array( $this->config->get( 'CookieWarningForCountryCodes' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $currentIP
|
||||
* @return bool|mixed|null|string
|
||||
* @throws ConfigException
|
||||
*/
|
||||
private function getCountryCodeFromIP( $currentIP ) {
|
||||
$cacheKey = $this->cache->makeGlobalKey( __CLASS__, self::CACHE_KEY . $currentIP );
|
||||
$lookedUpCountryCode = $this->cache->get( $cacheKey );
|
||||
|
||||
if ( is_string( $lookedUpCountryCode ) ) {
|
||||
return $lookedUpCountryCode;
|
||||
}
|
||||
|
||||
wfDebugLog( 'CookieWarning', 'Try to locate the user\'s IP address.' );
|
||||
$located = $this->geoLocation->locate( $currentIP );
|
||||
if ( !$located ) {
|
||||
wfDebugLog( 'CookieWarning',
|
||||
'Locating the user\'s IP address failed or is' . ' configured false.' );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$lookedUpCountryCode = $this->geoLocation->getCountryCode();
|
||||
$this->cache->set( $cacheKey, $lookedUpCountryCode );
|
||||
|
||||
wfDebugLog( 'CookieWarning', 'Locating the user was successful, located' . ' region: ' .
|
||||
$lookedUpCountryCode );
|
||||
|
||||
return $lookedUpCountryCode;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,6 @@ return [
|
|||
},
|
||||
'CookieWarning.Decisions' => function ( MediaWikiServices $services ) {
|
||||
return new CookieWarningDecisions( $services->getService( 'CookieWarning.Config' ),
|
||||
$services->getService( 'GeoLocation' ) );
|
||||
$services->getService( 'GeoLocation' ), $services->getMainWANObjectCache() );
|
||||
},
|
||||
];
|
||||
|
|
34
tests/phpunit/includes/CookieWarningDecisionsTest.php
Normal file
34
tests/phpunit/includes/CookieWarningDecisionsTest.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
class CookieWarningDecisionsTest extends MediaWikiTestCase {
|
||||
/**
|
||||
* @covers CookieWarningDecisions::shouldShowCookieWarning()
|
||||
* @throws ConfigException
|
||||
* @throws MWException
|
||||
*/
|
||||
public function testShouldNotCallGeoLocationMultiple() {
|
||||
$this->setMwGlobals( [
|
||||
'wgCookieWarningEnabled' => true,
|
||||
'wgCookieWarningGeoIPLookup' => 'php',
|
||||
'wgCookieWarningForCountryCodes' => [ 'EU' => 'European Union' ],
|
||||
] );
|
||||
|
||||
$geoLocation = $this->getMockBuilder( GeoLocation::class )
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$geoLocation->method( 'locate' )->willReturn( true );
|
||||
$geoLocation->method( 'getCountryCode' )->willReturn( 'EU' );
|
||||
|
||||
$geoLocation->expects( $this->once() )->method( 'locate' );
|
||||
$cookieWarningDecisions = new CookieWarningDecisions(
|
||||
MediaWikiServices::getInstance()->getService( 'CookieWarning.Config' ),
|
||||
$geoLocation,
|
||||
new WANObjectCache( [ 'cache' => new HashBagOStuff() ] )
|
||||
);
|
||||
|
||||
$cookieWarningDecisions->shouldShowCookieWarning( RequestContext::getMain() );
|
||||
$cookieWarningDecisions->shouldShowCookieWarning( RequestContext::getMain() );
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue