Tim Starling has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/206999

Change subject: [WIP] Central list feature and BV 2015 list script
......................................................................

[WIP] Central list feature and BV 2015 list script

* Add a "need-central-list" election property, which checks to see if
  the user's gu_id is linked to a row in the securepoll_lists table in
  the centralauth DB. This is needed to implement the feature
  requirement that a user be allowed to vote by clicking on a link in
  meta, instead of returning to their "home wiki" as in previous years.
  Some qualified users will not have a user_id in metawiki at the time
  of the list creation, and it would be inefficient to autocreate one
  for the tens of millions of affected users.

* Add the list script for Board and FDC 2015 elections. This is similar
  to the 2013 one, except that it ignores local attachment and writes
  the list to the centralauth database.

Bug: T95262
Change-Id: I422d390c08fc91011c2563f15a52e1a70a2bb684
---
A cli/wm-scripts/bv2015/voterList.php
M includes/entities/Election.php
M includes/user/Auth.php
3 files changed, 162 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/SecurePoll 
refs/changes/99/206999/1

diff --git a/cli/wm-scripts/bv2015/voterList.php 
b/cli/wm-scripts/bv2015/voterList.php
new file mode 100644
index 0000000..0f72964
--- /dev/null
+++ b/cli/wm-scripts/bv2015/voterList.php
@@ -0,0 +1,125 @@
+<?php
+
+require( dirname( __FILE__ ) . '/../../cli.inc' );
+$dbcr = CentralAuthUser::getCentralSlaveDB();
+$dbcw = CentralAuthUser::getCentralDB();
+
+$fname = 'voterList.php';
+$listName = 'board-vote-2015';
+
+$dbcw->delete( 'securepoll_lists', array( 'li_name' => $listName ), $fname );
+
+$userName = '';
+$wikis = array();
+$numQualified = 0;
+$insertBatch = array();
+while ( true ) {
+       $res = $dbcr->select( 'globaluser',
+               array( 'gu_id', 'gu_name' ),
+               array( 'gu_name > ' . $dbcr->addQuotes( $userName ) ),
+               $fname,
+               array( 'LIMIT' => 1000, 'ORDER BY' => 'gu_name' ) );
+       if ( !$res->numRows() ) {
+               break;
+       }
+
+       $userIds = array();
+       foreach ( $res as $row ) {
+               $users[$row->gu_id] = $row->gu_name;
+       }
+
+       $qualifieds = spGetQualifiedUsers( $users );
+       $insertBatch = array();
+       foreach ( $qualifieds as $id => $name ) {
+               $insertBatch[] = array(
+                       'li_name' => $listName,
+                       'li_member' => $id
+               );
+       }
+       if ( $insertBatch ) {
+               $dbcw->insert( 'securepoll_lists', $insertBatch, $fname );
+               $numQualified += count( $insertBatch );
+       }
+}
+echo wfWikiID() . " qualified \t$numQualified\n";
+
+/**
+ * @param $users array
+ * @return array
+ */
+function spGetQualifiedUsers( $users ) {
+       global $wgLocalDatabases;
+       $dbcr = CentralAuthUser::getCentralSlaveDB();
+
+       $res = $dbcr->select( 'localuser',
+               array( 'lu_name', 'lu_wiki' ),
+               array( 'lu_name' => $users ),
+               __METHOD__ );
+
+       $editCounts = array();
+       $foreignUsers = array();
+       foreach ( $res as $row ) {
+               $foreignUsers[$row->lu_wiki][] = $row->lu_name;
+               $editCounts[$row->lu_name] = array( 0, 0 );
+       }
+
+       foreach ( $foreignUsers as $wiki => $wikiUsers ) {
+               if ( !in_array( $wiki, $wgLocalDatabases ) ) {
+                       continue;
+               }
+               $lb = wfGetLB( $wiki );
+               $db = $lb->getConnection( DB_SLAVE, array(), $wiki );
+               $foreignEditCounts = spGetEditCounts( $db, $wikiUsers );
+               $lb->reuseConnection( $db );
+               foreach ( $foreignEditCounts as $name => $count ) {
+                       $editCounts[$name][0] += $count[0];
+                       $editCounts[$name][1] += $count[1];
+               }
+       }
+
+       $idsByUser = array_flip( $users );
+       $qualifiedUsers = array();
+       foreach ( $editCounts as $user => $count ) {
+               if ( spIsQualified( $count[0], $count[1] ) ) {
+                       $id = $idsByUser[$user];
+                       $qualifiedUsers[$id] = $user;
+               }
+       }
+
+       return $qualifiedUsers;
+}
+
+/**
+ * @param $db DatabaseBase
+ * @param $userNames
+ * @return array
+ */
+function spGetEditCounts( $db, $userNames ) {
+       $res = $db->select(
+               array( 'user', 'bv2015_edits' ),
+               array( 'user_name', 'bv_long_edits', 'bv_short_edits' ),
+               array( 'bv_user=user_id', 'user_name' => $userNames ),
+               __METHOD__
+       );
+       $editCounts = array();
+       foreach ( $res as $row ) {
+               $editCounts[$row->user_name] = array( $row->bv_short_edits, 
$row->bv_long_edits );
+       }
+       foreach ( $userNames as $user ) {
+               if ( !isset( $editCounts[$user] ) ) {
+                       $editCounts[$user] = array( 0, 0 );
+               }
+       }
+       return $editCounts;
+}
+
+/**
+ * Returns whether a user "is qualified" to vote based on edit count
+ *
+ * @param $short
+ * @param $long
+ * @return bool
+ */
+function spIsQualified( $short, $long ) {
+       return $short >= 20 && $long >= 300;
+}
diff --git a/includes/entities/Election.php b/includes/entities/Election.php
index 713d3c9..29c0566 100644
--- a/includes/entities/Election.php
+++ b/includes/entities/Election.php
@@ -27,6 +27,9 @@
  *              The name of an MW group voters need to be in
  *          need-list
  *              The name of a SecurePoll list voters need to be in
+ *          need-central-list
+ *              The name of a list in the CentralAuth database which is linked
+ *              to globaluser.gu_id
  *          include-list
  *              The name of a SecurePoll list of voters who can vote 
regardless of the above
  *          exclude-list
@@ -169,6 +172,7 @@
                $status = Status::newGood();
 
                $lists = isset( $props['lists'] ) ? $props['lists'] : array();
+               $centralLists = isset( $props['central-lists'] ) ? 
$props['central-lists'] : array();
                $includeList = $this->getProperty( 'include-list' );
                $excludeList = $this->getProperty( 'exclude-list' );
 
@@ -231,6 +235,11 @@
                        if ( $needList && !in_array( $needList, $lists ) ) {
                                $status->fatal( 'securepoll-not-in-list' );
                        }
+
+                       $needCentralList = $this->getProperty( 
'need-central-list' );
+                       if ( $needCentralList && !in_array( $needCentralList, 
$centralLists ) ) {
+                               $status->fatal( 'securepoll-not-in-list' );
+                       }
                }
 
                # Get custom error message
diff --git a/includes/user/Auth.php b/includes/user/Auth.php
index 2075a27..0e8c4fd 100644
--- a/includes/user/Auth.php
+++ b/includes/user/Auth.php
@@ -228,6 +228,7 @@
                                'language' => $user->getOption( 'language' ),
                                'groups' => $user->getGroups(),
                                'lists' => $this->getLists( $user ),
+                               'central-lists' => $this->getCentralLists( 
$user ),
                                'registration' => $user->getRegistration(),
                        )
                );
@@ -257,6 +258,33 @@
        }
 
        /**
+        * Get the CentralAuth lists the user belongs to
+        * @param $user User
+        * @return array
+        */
+       function getCentralLists( $user ) {
+               if ( !class_exists( 'CentralAuthUser' ) ) {
+                       return array();
+               }
+               $centralUser = CentralAuthUser::getInstance( $user );
+               if ( !$centralUser->isAttached() ) {
+                       return array();
+               }
+               $dbc = CentralAuthUser::getSlaveDB();
+               $res = $dbc->select(
+                       'securepoll_lists',
+                       array( 'li_name' ),
+                       array( 'li_member' => $centralUser->getId() ),
+                       __METHOD__
+               );
+               $lists = array();
+               foreach ( $res as $row ) {
+                       $lists[] = $row->li_name;
+               }
+               return $lists;
+       }
+
+       /**
         * Checks how many central wikis the user is blocked on
         * @param $user User
         * @return Integer the number of wikis the user is blocked on.

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I422d390c08fc91011c2563f15a52e1a70a2bb684
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/SecurePoll
Gerrit-Branch: master
Gerrit-Owner: Tim Starling <tstarl...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to