MaxSem has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/350961 )

Change subject: Automatically purge expired user groups
......................................................................

Automatically purge expired user groups

We already check for expired groups when we load them, so
is we see any just purge them via a job. Adds a new hook
to inform extensions about that, so that Echo could inform
users when their rights expire.

Bug: T153817
Change-Id: I35d50e9dfa72c0dc3cc9ff5782369debd14c2e61
---
M RELEASE-NOTES-1.30
M autoload.php
M docs/hooks.txt
M includes/DefaultSettings.php
A includes/jobqueue/jobs/UserGroupExpiryJob.php
M includes/user/UserGroupMembership.php
6 files changed, 67 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/61/350961/1

diff --git a/RELEASE-NOTES-1.30 b/RELEASE-NOTES-1.30
index 3c1ae8d..4812eff 100644
--- a/RELEASE-NOTES-1.30
+++ b/RELEASE-NOTES-1.30
@@ -39,7 +39,9 @@
 * …
 
 === Other changes in 1.30 ===
-* …
+* Expired user group memberships are now automatically purged next time they
+  are loaded.
+* New hook UserGroupsExpired is triggered when the above happens.
 
 == Compatibility ==
 MediaWiki 1.30 requires PHP 5.5.9 or later. There is experimental support for
diff --git a/autoload.php b/autoload.php
index 1141c39..da3d690 100644
--- a/autoload.php
+++ b/autoload.php
@@ -1533,6 +1533,7 @@
        'UserBlockedError' => __DIR__ . 
'/includes/exception/UserBlockedError.php',
        'UserCache' => __DIR__ . '/includes/cache/UserCache.php',
        'UserDupes' => __DIR__ . '/maintenance/userDupes.inc',
+       'UserGroupExpiryJob' => __DIR__ . 
'/includes/jobqueue/jobs/UserGroupExpiryJob.php',
        'UserGroupMembership' => __DIR__ . 
'/includes/user/UserGroupMembership.php',
        'UserMailer' => __DIR__ . '/includes/mail/UserMailer.php',
        'UserNamePrefixSearch' => __DIR__ . 
'/includes/user/UserNamePrefixSearch.php',
diff --git a/docs/hooks.txt b/docs/hooks.txt
index 7c09a55..10de391 100644
--- a/docs/hooks.txt
+++ b/docs/hooks.txt
@@ -3599,6 +3599,9 @@
 $newUGMs: An associative array (group name => UserGroupMembership object) of
 the user's current group memberships.
 
+'UserGroupsExpired': Called after one or more users' expired groups have been 
removed.
+$removals: Removed groups by user ID, e.g. [ userID => [ 'right1', 'right2' ] ]
+
 'UserIsBlockedFrom': Check if a user is blocked from a specific page (for
 specific block exemptions).
 $user: User in question
diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index 299757c..6ab3bfe 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -7352,6 +7352,7 @@
        'categoryMembershipChange' => 'CategoryMembershipChangeJob',
        'cdnPurge' => 'CdnPurgeJob',
        'enqueue' => 'EnqueueJob', // local queue for multi-DC setups
+       'userGroupExpiry' => 'UserGroupExpiryJob',
        'null' => 'NullJob'
 ];
 
diff --git a/includes/jobqueue/jobs/UserGroupExpiryJob.php 
b/includes/jobqueue/jobs/UserGroupExpiryJob.php
new file mode 100644
index 0000000..ec9bc24
--- /dev/null
+++ b/includes/jobqueue/jobs/UserGroupExpiryJob.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Job that purges expired user group memberships.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup JobQueue
+ */
+
+class UserGroupExpiryJob extends Job {
+       public function __construct( Title $title, $params = false ) {
+               parent::__construct( 'userGroupExpiry', $title, $params );
+       }
+
+       /**
+        * Run the job
+        * @return bool Success
+        */
+       public function run() {
+               UserGroupMembership::purgeExpired();
+
+               return true;
+       }
+}
diff --git a/includes/user/UserGroupMembership.php 
b/includes/user/UserGroupMembership.php
index e8b22c4..a8f16c3 100644
--- a/includes/user/UserGroupMembership.php
+++ b/includes/user/UserGroupMembership.php
@@ -294,8 +294,10 @@
 
                                // save an array of users/groups to insert to 
user_former_groups
                                $usersAndGroups = [];
+                               $groupsByUser = [];
                                foreach ( $res as $row ) {
                                        $usersAndGroups[] = [ 'ufg_user' => 
$row->ug_user, 'ufg_group' => $row->ug_group ];
+                                       $groupsByUser[$row->ug_user][] = 
$row->ug_group;
                                }
 
                                // delete 'em all
@@ -303,6 +305,10 @@
 
                                // and push the groups to user_former_groups
                                $dbw->insert( 'user_former_groups', 
$usersAndGroups, __METHOD__, [ 'IGNORE' ] );
+
+                               if ( $groupsByUser ) {
+                                       Hooks::run( 'UserGroupsExpired', [ 
$groupsByUser ] );
+                               }
                        }
                ) );
        }
@@ -326,18 +332,32 @@
                        __METHOD__ );
 
                $ugms = [];
+               $haveExpiries = false;
                foreach ( $res as $row ) {
                        $ugm = self::newFromRow( $row );
                        if ( !$ugm->isExpired() ) {
                                $ugms[$ugm->group] = $ugm;
+                               $haveExpiries = true;
                        }
                }
-               ksort( $ugms );
+               if ( $haveExpiries ) {
+                       self::purgeExpiredViaJob();
+               }
 
+               ksort( $ugms );
                return $ugms;
        }
 
        /**
+        * Enqueues a job to purge expired user groups
+        */
+       public static function purgeExpiredViaJob() {
+               $job = new UserGroupExpiryJob( Title::newMainPage() );
+
+               JobQueueGroup::singleton()->push( $job );
+       }
+
+       /**
         * Returns a UserGroupMembership object that pertains to the given user 
and group,
         * or false if the user does not belong to that group (or the 
assignment has
         * expired).

-- 
To view, visit https://gerrit.wikimedia.org/r/350961
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I35d50e9dfa72c0dc3cc9ff5782369debd14c2e61
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: MaxSem <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to