mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/LoginNotify
synced 2024-11-11 16:49:30 +00:00
Use the new DatabaseVirtualDomains feature
Change-Id: I05b6361bd57ba6754bd308e04da1c635f95d042b
This commit is contained in:
parent
70703bdce3
commit
6f32dafbc1
33
README.md
33
README.md
|
@ -7,25 +7,14 @@ The LoginNotify extension notifies you when someone logs into your account. It c
|
||||||
* Navigate to Special:Version on your wiki to verify that the extension is successfully installed.
|
* Navigate to Special:Version on your wiki to verify that the extension is successfully installed.
|
||||||
|
|
||||||
#### Configuration parameters
|
#### Configuration parameters
|
||||||
"@doc": "The number of failed login attempts to permit from a known IP before a notification is triggered.",
|
|
||||||
"LoginNotifyAttemptsKnownIP": 10
|
See extension.json.
|
||||||
"@doc": "The time-to-live of the count of failed login attempts from a known IP (from the time of the first failed attempt).",
|
|
||||||
"LoginNotifyExpiryKnownIP": 604800,
|
To place the loginnotify_seen_net table in a shared database, use
|
||||||
"@doc": "The number of failed login attempts to permit from a new IP before a notification is triggered.",
|
|
||||||
"LoginNotifyAttemptsNewIP": 3,
|
```php
|
||||||
"@doc": "The time-to-live of the count of failed login attempts from a new IP (from the time of the first failed attempt).",
|
$wgVirtualDomainsMapping['virtual-LoginNotify'] = [
|
||||||
"LoginNotifyExpiryNewIP": 1209600,
|
'db' => '<shared database name>'
|
||||||
"@doc": "Whether to trigger a notification after failed logins from known IPs.",
|
];
|
||||||
"LoginNotifyCheckKnownIPs": true,
|
$wgLoginNotifyUseCentralId = true;
|
||||||
"@doc": "Whether to trigger a notification after successful logins from unknown IPs.",
|
```
|
||||||
"LoginNotifyEnableOnSuccess": true,
|
|
||||||
"@doc": "Override this to use a different secret than $wgSecretKey",
|
|
||||||
"LoginNotifySecretKey": null,
|
|
||||||
"@doc": "Expiry in seconds. Default is 180 days",
|
|
||||||
"LoginNotifyCookieExpire": 15552000,
|
|
||||||
"@doc": "Override to allow sharing login cookies between sites on different subdomains",
|
|
||||||
"LoginNotifyCookieDomain": null,
|
|
||||||
"@doc": "Maximum number of users (records) to track as having successfully logged in on a particular device.",
|
|
||||||
"LoginNotifyMaxCookieRecords": 6,
|
|
||||||
"@doc": "Set to false to disable caching IPs in memcache. Set to 0 to cache forever. Default 60 days.",
|
|
||||||
"LoginNotifyCacheLoginIPExpiry": 5184000
|
|
||||||
|
|
|
@ -67,6 +67,9 @@
|
||||||
"ServiceWiringFiles": [
|
"ServiceWiringFiles": [
|
||||||
"includes/ServiceWiring.php"
|
"includes/ServiceWiring.php"
|
||||||
],
|
],
|
||||||
|
"DatabaseVirtualDomains": [
|
||||||
|
"virtual-LoginNotify"
|
||||||
|
],
|
||||||
"config": {
|
"config": {
|
||||||
"LoginNotifyAttemptsKnownIP": {
|
"LoginNotifyAttemptsKnownIP": {
|
||||||
"description": "The number of failed login attempts to permit from a known IP before a notification is triggered.",
|
"description": "The number of failed login attempts to permit from a known IP before a notification is triggered.",
|
||||||
|
@ -112,14 +115,6 @@
|
||||||
"description": "Set to false to disable caching IPs in memcache. Set to 0 to cache forever. Default 60 days.",
|
"description": "Set to false to disable caching IPs in memcache. Set to 0 to cache forever. Default 60 days.",
|
||||||
"value": 5184000
|
"value": 5184000
|
||||||
},
|
},
|
||||||
"LoginNotifySeenDatabase": {
|
|
||||||
"description": "The database to store the loginnotify_seen_net table. This can be a shared database if CentralIdLookupProvider is configured to return a unique ID for the user.",
|
|
||||||
"value": null
|
|
||||||
},
|
|
||||||
"LoginNotifySeenCluster": {
|
|
||||||
"description": "The external cluster to store the loginnotify_seen_net table in. The default is to store it in the core database.",
|
|
||||||
"value": null
|
|
||||||
},
|
|
||||||
"LoginNotifyUseCheckUser": {
|
"LoginNotifyUseCheckUser": {
|
||||||
"description": "Use the CheckUser cu_changes table if it is available. This is redundant with LoginNotify's own table, available with MediaWiki 1.41. Setting this to true will be deprecated in a later release. Defaults to true temporarily during WMF pilot.",
|
"description": "Use the CheckUser cu_changes table if it is available. This is redundant with LoginNotify's own table, available with MediaWiki 1.41. Setting this to true will be deprecated in a later release. Defaults to true temporarily during WMF pilot.",
|
||||||
"value": true
|
"value": true
|
||||||
|
@ -128,6 +123,10 @@
|
||||||
"description": "Use the loginnotify_seen_net table. This is redundant with LoginNotifyUseCheckUser although both can be enabled during migration. Defaults to false temporarily during WMF pilot.",
|
"description": "Use the loginnotify_seen_net table. This is redundant with LoginNotifyUseCheckUser although both can be enabled during migration. Defaults to false temporarily during WMF pilot.",
|
||||||
"value": false
|
"value": false
|
||||||
},
|
},
|
||||||
|
"LoginNotifyUseCentralId": {
|
||||||
|
"description": "Use central user IDs in the loginnotify_seen_net table. This should be set to true if the loginnotify_seen_net is in a shared database. CentralAuth should be installed and all users should be attached to it.",
|
||||||
|
"value": false
|
||||||
|
},
|
||||||
"LoginNotifySeenExpiry": {
|
"LoginNotifySeenExpiry": {
|
||||||
"description": "The expiry time of data in the loginnotify_seen_net table, in seconds. This should be a multiple of LoginNotifyBucketSize. Default is 180 days.",
|
"description": "The expiry time of data in the loginnotify_seen_net table, in seconds. This should be a multiple of LoginNotifyBucketSize. Default is 180 days.",
|
||||||
"value": 15552000
|
"value": 15552000
|
||||||
|
|
|
@ -30,7 +30,6 @@ use WebRequest;
|
||||||
use Wikimedia\Assert\Assert;
|
use Wikimedia\Assert\Assert;
|
||||||
use Wikimedia\IPUtils;
|
use Wikimedia\IPUtils;
|
||||||
use Wikimedia\Rdbms\IDatabase;
|
use Wikimedia\Rdbms\IDatabase;
|
||||||
use Wikimedia\Rdbms\ILoadBalancer;
|
|
||||||
use Wikimedia\Rdbms\IMaintainableDatabase;
|
use Wikimedia\Rdbms\IMaintainableDatabase;
|
||||||
use Wikimedia\Rdbms\IReadableDatabase;
|
use Wikimedia\Rdbms\IReadableDatabase;
|
||||||
use Wikimedia\Rdbms\LBFactory;
|
use Wikimedia\Rdbms\LBFactory;
|
||||||
|
@ -55,11 +54,10 @@ class LoginNotify implements LoggerAwareInterface {
|
||||||
'LoginNotifyMaxCookieRecords',
|
'LoginNotifyMaxCookieRecords',
|
||||||
'LoginNotifySecretKey',
|
'LoginNotifySecretKey',
|
||||||
'LoginNotifySeenBucketSize',
|
'LoginNotifySeenBucketSize',
|
||||||
'LoginNotifySeenCluster',
|
|
||||||
'LoginNotifySeenDatabase',
|
|
||||||
'LoginNotifySeenExpiry',
|
'LoginNotifySeenExpiry',
|
||||||
'LoginNotifyUseCheckUser',
|
'LoginNotifyUseCheckUser',
|
||||||
'LoginNotifyUseSeenTable',
|
'LoginNotifyUseSeenTable',
|
||||||
|
'LoginNotifyUseCentralId',
|
||||||
'SecretKey',
|
'SecretKey',
|
||||||
'UpdateRowsPerQuery'
|
'UpdateRowsPerQuery'
|
||||||
];
|
];
|
||||||
|
@ -418,8 +416,7 @@ class LoginNotify implements LoggerAwareInterface {
|
||||||
* @return IReadableDatabase
|
* @return IReadableDatabase
|
||||||
*/
|
*/
|
||||||
private function getSeenReplicaDb(): IReadableDatabase {
|
private function getSeenReplicaDb(): IReadableDatabase {
|
||||||
$dbName = $this->config->get( 'LoginNotifySeenDatabase' ) ?? false;
|
return $this->lbFactory->getReplicaDatabase( 'virtual-LoginNotify' );
|
||||||
return $this->getSeenLoadBalancer()->getConnection( DB_REPLICA, [], $dbName );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -428,33 +425,7 @@ class LoginNotify implements LoggerAwareInterface {
|
||||||
* @return IDatabase
|
* @return IDatabase
|
||||||
*/
|
*/
|
||||||
private function getSeenPrimaryDb(): IDatabase {
|
private function getSeenPrimaryDb(): IDatabase {
|
||||||
$dbName = $this->config->get( 'LoginNotifySeenDatabase' ) ?? false;
|
return $this->lbFactory->getPrimaryDatabase( 'virtual-LoginNotify' );
|
||||||
return $this->getSeenLoadBalancer()->getConnection( DB_PRIMARY, [], $dbName );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is the database holding the loginnotify_seen_net table replicated to
|
|
||||||
* multiple servers?
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
private function isSeenDbReplicated() {
|
|
||||||
return $this->getSeenLoadBalancer()->hasReplicaServers();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the LoadBalancer holding the loginnotify_seen_net table.
|
|
||||||
*
|
|
||||||
* @return ILoadBalancer
|
|
||||||
*/
|
|
||||||
private function getSeenLoadBalancer() {
|
|
||||||
$cluster = $this->config->get( 'LoginNotifySeenCluster' );
|
|
||||||
if ( $cluster ) {
|
|
||||||
return $this->lbFactory->getExternalLB( $cluster );
|
|
||||||
} else {
|
|
||||||
$dbName = $this->config->get( 'LoginNotifySeenDatabase' ) ?? false;
|
|
||||||
return $this->lbFactory->getMainLB( $dbName );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -497,7 +468,7 @@ class LoginNotify implements LoggerAwareInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If LoginNotifySeenDatabase is configured, indicating a shared table,
|
* If LoginNotifyUseCentralId is true, indicating a shared table,
|
||||||
* get the central user ID. Otherwise, get the local user ID.
|
* get the central user ID. Otherwise, get the local user ID.
|
||||||
*
|
*
|
||||||
* If CentralAuth is not installed, $this->centralIdLookup will be a
|
* If CentralAuth is not installed, $this->centralIdLookup will be a
|
||||||
|
@ -509,7 +480,7 @@ class LoginNotify implements LoggerAwareInterface {
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
private function getMaybeCentralId( User $user ) {
|
private function getMaybeCentralId( User $user ) {
|
||||||
if ( ( $this->config->get( 'LoginNotifySeenDatabase' ) ?? false ) !== false ) {
|
if ( $this->config->get( 'LoginNotifyUseCentralId' ) ) {
|
||||||
return $this->centralIdLookup->centralIdFromLocalUser( $user );
|
return $this->centralIdLookup->centralIdFromLocalUser( $user );
|
||||||
} else {
|
} else {
|
||||||
return $user->getId();
|
return $user->getId();
|
||||||
|
@ -802,17 +773,9 @@ class LoginNotify implements LoggerAwareInterface {
|
||||||
|
|
||||||
// Insert a row
|
// Insert a row
|
||||||
$dbw = $this->getSeenPrimaryDb();
|
$dbw = $this->getSeenPrimaryDb();
|
||||||
$isReplicated = $this->isSeenDbReplicated();
|
|
||||||
$fname = __METHOD__;
|
$fname = __METHOD__;
|
||||||
$dbw->onTransactionCommitOrIdle(
|
$dbw->onTransactionCommitOrIdle(
|
||||||
function () use ( $dbw, $id, $hash, $isReplicated, $fname ) {
|
function () use ( $dbw, $id, $hash, $fname ) {
|
||||||
// Check if the user/hash is in the primary DB, as late as
|
|
||||||
// possible before the insert. (Trying to reduce the number of
|
|
||||||
// no-op queries in the binlog)
|
|
||||||
if ( $isReplicated && $this->userIsInCurrentSeenBucket( $id, $hash, true ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$dbw->newInsertQueryBuilder()
|
$dbw->newInsertQueryBuilder()
|
||||||
->insert( 'loginnotify_seen_net' )
|
->insert( 'loginnotify_seen_net' )
|
||||||
->ignore()
|
->ignore()
|
||||||
|
|
|
@ -38,10 +38,9 @@ class LoginNotifyTest extends MediaWikiIntegrationTestCase {
|
||||||
"LoginNotifyCookieDomain" => null,
|
"LoginNotifyCookieDomain" => null,
|
||||||
"LoginNotifyMaxCookieRecords" => 6,
|
"LoginNotifyMaxCookieRecords" => 6,
|
||||||
"LoginNotifyCacheLoginIPExpiry" => 60 * $day,
|
"LoginNotifyCacheLoginIPExpiry" => 60 * $day,
|
||||||
'LoginNotifySeenCluster' => null,
|
|
||||||
"LoginNotifySeenDatabase" => null,
|
|
||||||
"LoginNotifyUseCheckUser" => false,
|
"LoginNotifyUseCheckUser" => false,
|
||||||
"LoginNotifyUseSeenTable" => true,
|
"LoginNotifyUseSeenTable" => true,
|
||||||
|
"LoginNotifyUseCentralId" => false,
|
||||||
"LoginNotifySeenExpiry" => 180 * $day,
|
"LoginNotifySeenExpiry" => 180 * $day,
|
||||||
"LoginNotifySeenBucketSize" => 15 * $day,
|
"LoginNotifySeenBucketSize" => 15 * $day,
|
||||||
"UpdateRowsPerQuery" => 100,
|
"UpdateRowsPerQuery" => 100,
|
||||||
|
|
Loading…
Reference in a new issue