mediawiki-extensions-Cookie.../includes/Decisions.php
Florian Schmidt 7afcc5bfd7 Show cookiewarning banner if IP could not be located
If any error occured during locating the IP address, the extension should
assume, that the user is in a configured region and show the cookie warning,
if not already dismissed.

Bug: T200077
Change-Id: Ib7f0dd0a135071924281a576ab24887d5e226435
2018-07-20 14:22:47 +02:00

110 lines
3.1 KiB
PHP

<?php
namespace CookieWarning;
use Config;
use ConfigException;
use IContextSource;
use MWException;
use WANObjectCache;
class Decisions {
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, WANObjectCache $cache ) {
$this->config = $config;
$this->geoLocation = $geoLocation;
$this->cache = $cache;
}
/**
* Checks, if the CookieWarning information bar should be visible to this user on
* this page.
*
* @param IContextSource $context
* @return bool Returns true, if the cookie warning should be visible, false otherwise.
* @throws ConfigException
* @throws MWException
*/
public function shouldShowCookieWarning( IContextSource $context ) {
$user = $context->getUser();
return $this->config->get( 'CookieWarningEnabled' ) &&
!$user->getBoolOption( 'cookiewarning_dismissed', false ) &&
!$context->getRequest()->getCookie( 'cookiewarning_dismissed' ) &&
( $this->config->get( 'CookieWarningGeoIPLookup' ) === 'js' ||
$this->isInConfiguredRegion( $context ) );
}
/**
* Checks, if the user is in one of the configured regions.
*
* @param IContextSource $context
* @return bool
* @throws ConfigException
* @throws MWException
*/
private function isInConfiguredRegion( IContextSource $context ) {
if ( !$this->config->get( 'CookieWarningForCountryCodes' ) ||
$this->config->get( 'CookieWarningGeoIPLookup' ) === 'none' ) {
wfDebugLog( 'CookieWarning', 'IP geolocation not configured, skipping.' );
return true;
}
$countryCode = $this->getCountryCodeFromIP( $context->getRequest()->getIP() );
return $countryCode === '' || array_key_exists( $countryCode,
$this->config->get( 'CookieWarningForCountryCodes' ) );
}
/**
* @return bool
* @throws ConfigException
*/
public function shouldAddResourceLoaderComponents() {
return $this->config->get( 'CookieWarningGeoIPLookup' ) === 'js' &&
is_array( $this->config->get( 'CookieWarningForCountryCodes' ) );
}
/**
* @param $currentIP
* @return string The country code associated with the IP or empty string if not able to locate.
* @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 misconfigured.' );
return '';
}
$lookedUpCountryCode = $this->geoLocation->getCountryCode();
$this->cache->set( $cacheKey, $lookedUpCountryCode );
wfDebugLog( 'CookieWarning', 'Locating the user was successful, located' . ' region: ' .
$lookedUpCountryCode );
return $lookedUpCountryCode;
}
}