Page MenuHomeWickedGov Phorge

ApiQueryGlobalAllUsers.php
No OneTemporary

Size
9 KB
Referenced Files
None
Subscribers
None

ApiQueryGlobalAllUsers.php

<?php
namespace MediaWiki\Extension\CentralAuth\Api;
use MediaWiki\Api\ApiBase;
use MediaWiki\Api\ApiQuery;
use MediaWiki\Api\ApiQueryBase;
use MediaWiki\Extension\CentralAuth\CentralAuthDatabaseManager;
use MediaWiki\Extension\CentralAuth\GlobalGroup\GlobalGroupLookup;
use MediaWiki\Extension\CentralAuth\User\CentralAuthUser;
use MediaWiki\User\TempUser\TempUserConfig;
use MediaWiki\WikiMap\WikiMap;
use Wikimedia\ParamValidator\ParamValidator;
use Wikimedia\ParamValidator\TypeDef\IntegerDef;
use Wikimedia\Rdbms\IExpression;
use Wikimedia\Rdbms\IReadableDatabase;
use Wikimedia\Rdbms\IResultWrapper;
use Wikimedia\Rdbms\LikeValue;
/**
* Api module for CentralAuth extension to list all global users.
* Partly based on ApiQueryAllUsers.
*
* 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
*
* @ingroup API
* @ingroup Extensions
*
* @license GPL-2.0-or-later
* @author Marius Hoch < hoo@online.de >
*/
class ApiQueryGlobalAllUsers extends ApiQueryBase {
private TempUserConfig $tempUserConfig;
private CentralAuthDatabaseManager $databaseManager;
private GlobalGroupLookup $globalGroupLookup;
public function __construct(
ApiQuery $query,
string $moduleName,
TempUserConfig $tempUserConfig,
CentralAuthDatabaseManager $databaseManager,
GlobalGroupLookup $globalGroupLookup
) {
parent::__construct( $query, $moduleName, 'agu' );
$this->tempUserConfig = $tempUserConfig;
$this->databaseManager = $databaseManager;
$this->globalGroupLookup = $globalGroupLookup;
}
/**
* Get the Query database connection (read-only)
*
* @see ApiQueryBase::getDB
* @return IReadableDatabase
*/
protected function getDB() {
static $db = null;
if ( $db === null ) {
$db = $this->databaseManager->getCentralReplicaDB();
}
return $db;
}
/**
* This function converts the user name to a canonical form
* which is stored in the database.
* @param string $name
* @return string
*/
private function getCanonicalUserName( $name ) {
return str_replace( '_', ' ', $name );
}
public function execute() {
$params = $this->extractRequestParams();
$prop = array_flip( (array)$params['prop'] );
$dir = ( $params['dir'] == 'descending' ? 'older' : 'newer' );
$db = $this->getDB();
$this->addTables( 'globaluser' );
$this->addFields( [ 'gu_id', 'gu_name' ] );
$limit = intval( $params['limit'] ) + 1;
$this->addWhereRange(
'gu_name',
$dir,
isset( $params['from'] ) ? $this->getCanonicalUserName( $params['from'] ) : null,
isset( $params['to'] ) ? $this->getCanonicalUserName( $params['to'] ) : null
);
if ( $params['prefix'] !== null ) {
$this->addWhere(
$db->expr( 'gu_name', IExpression::LIKE,
new LikeValue( $this->getCanonicalUserName( $params['prefix'] ), $db->anyString() ) )
);
}
$this->requireMaxOneParameter( $params, 'group', 'excludegroup' );
if ( !empty( $params['group'] ) ) {
$this->addTables( 'global_user_groups' );
// Request more rows than needed to avoid not getting all rows
// that belong to one user, because a user might be in multiple groups
$limit += count( $params['group'] ) + 1;
$this->addJoinConds( [
'global_user_groups' =>
[ 'INNER JOIN', 'gug_user = gu_id' ]
] );
$this->addWhere( [ 'gug_group' => $params['group'] ] );
$this->addWhere( [
$this->getDB()->expr( 'gug_expiry', '=', null )
->or( 'gug_expiry', '>=', $this->getDB()->timestamp() )
] );
}
if ( !empty( $params['excludegroup'] ) ) {
$this->addTables( 'global_user_groups', 'gug2' );
$this->addJoinConds( [
'gug2' =>
[ 'LEFT OUTER JOIN', [ 'gug2.gug_user = gu_id', 'gug2.gug_group' => $params['excludegroup'] ] ]
] );
$this->addWhere( [ 'gug2.gug_user' => null ] );
$this->addWhere( [
$this->getDB()->expr( 'gug2.gug_expiry', '=', null )
->or( 'gug2.gug_expiry', '>=', $this->getDB()->timestamp() )
] );
}
$this->addWhere( [ 'gu_hidden_level' => CentralAuthUser::HIDDEN_LEVEL_NONE ] );
if ( isset( $prop['lockinfo'] ) ) {
$this->addFields( 'gu_locked' );
}
if ( isset( $prop['existslocally'] ) ) {
$this->addTables( 'localuser' );
$this->addFields( 'lu_wiki' );
$this->addJoinConds( [
'localuser' =>
[ 'LEFT OUTER JOIN', [ 'gu_name=lu_name', 'lu_wiki' => WikiMap::getCurrentWikiId() ] ]
] );
}
$excludeNamed = $params['excludenamed'];
$excludeTemp = $params['excludetemp'];
if ( $this->tempUserConfig->isKnown() ) {
if ( $excludeTemp ) {
$this->addWhere(
$this->tempUserConfig->getMatchCondition( $db, 'gu_name', IExpression::NOT_LIKE )
);
}
if ( $excludeNamed ) {
$this->addWhere(
$this->tempUserConfig->getMatchCondition( $db, 'gu_name', IExpression::LIKE )
);
}
}
$this->addOption( 'LIMIT', $limit );
$result = $this->select( __METHOD__ );
$groupsOfUser = [];
if ( isset( $prop['groups'] ) && $result->numRows() ) {
$groupsOfUser = $this->getGlobalGroups( $result, $dir );
}
$data = [];
$previousName = '';
$i = 1;
foreach ( $result as $row ) {
if ( $row->gu_name === $previousName ) {
continue;
}
$previousName = $row->gu_name;
if ( $i > $params['limit'] ) {
$this->setContinueEnumParameter( 'from', $row->gu_name );
break;
}
$i++;
$entry = [];
$entry['id'] = (int)$row->gu_id;
$entry['name'] = $row->gu_name;
if ( isset( $prop['groups'] ) ) {
if ( !empty( $groupsOfUser[$row->gu_id] ) ) {
$entry['groups'] = $groupsOfUser[$row->gu_id];
} else {
$entry['groups'] = [];
}
$this->getResult()->setIndexedTagName( $entry['groups'], 'group' );
}
if ( isset( $prop['existslocally'] ) && $row->lu_wiki != null ) {
$entry['existslocally'] = '';
}
if ( isset( $prop['lockinfo'] ) && $row->gu_locked ) {
$entry['locked'] = '';
}
$data[] = $entry;
}
$this->getResult()->setIndexedTagName( $data, 'globaluser' );
$this->getResult()->addValue( 'query', $this->getModuleName(), $data );
}
/**
* Get the global groups for the given global user result set.
*
* @param IResultWrapper $result Result of a globaluser table select
* @param string $dir Sorting directory
*
* @return string[][]
*/
protected function getGlobalGroups( IResultWrapper $result, $dir ) {
$this->resetQueryParams();
// Get all global groups now. We do this by using a WHERE
// range build from the given results
$groupsOfUser = [];
$this->addTables( [ 'globaluser', 'global_user_groups' ] );
$this->addFields( [ 'gug_user', 'gug_group' ] );
$result->seek( 0 );
$firstUser = $result->fetchObject()->gu_name;
$result->seek( $result->numRows() - 1 );
$lastUser = $result->fetchObject()->gu_name;
$this->addWhereRange(
'gu_name',
$dir,
$firstUser,
$lastUser,
false
);
// Use an INNER JOIN to only get users with global groups
$this->addJoinConds( [
'global_user_groups' =>
[ 'INNER JOIN', 'gug_user = gu_id' ]
] );
$this->addWhere( [
$this->getDB()->expr( 'gug_expiry', '=', null )
->or( 'gug_expiry', '>=', $this->getDB()->timestamp() )
] );
$groupResult = $this->select( __METHOD__ );
foreach ( $groupResult as $groupRow ) {
$groupsOfUser[$groupRow->gug_user][] = $groupRow->gug_group;
}
return $groupsOfUser;
}
/** @inheritDoc */
public function getAllowedParams() {
$globalGroups = $this->globalGroupLookup->getDefinedGroups();
return [
'from' => null,
'to' => null,
'prefix' => null,
'dir' => [
ParamValidator::PARAM_DEFAULT => 'ascending',
ParamValidator::PARAM_TYPE => [
'ascending',
'descending'
],
],
'group' => [
ParamValidator::PARAM_TYPE => $globalGroups,
ParamValidator::PARAM_ISMULTI => true,
],
'excludegroup' => [
ParamValidator::PARAM_TYPE => $globalGroups,
ParamValidator::PARAM_ISMULTI => true,
],
'prop' => [
ParamValidator::PARAM_ISMULTI => true,
ParamValidator::PARAM_TYPE => [
'lockinfo',
'groups',
'existslocally'
],
ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
],
'limit' => [
ParamValidator::PARAM_DEFAULT => 10,
ParamValidator::PARAM_TYPE => 'limit',
IntegerDef::PARAM_MIN => 1,
IntegerDef::PARAM_MAX => ApiBase::LIMIT_BIG1,
IntegerDef::PARAM_MAX2 => ApiBase::LIMIT_BIG2
],
'excludenamed' => [
ParamValidator::PARAM_TYPE => 'boolean',
],
'excludetemp' => [
ParamValidator::PARAM_TYPE => 'boolean',
],
];
}
/** @inheritDoc */
protected function getExamplesMessages() {
return [
'action=query&list=globalallusers'
=> 'apihelp-query+globalallusers-example-1',
'action=query&list=globalallusers&agufrom=ABC&aguprop=lockinfo|groups|existslocally'
=> 'apihelp-query+globalallusers-example-2',
];
}
}

File Metadata

Mime Type
text/x-php
Expires
Sat, Oct 3, 07:12 (2 w, 23 h ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
a5/88/6a263cd8e537d291feecf4804ae0
Default Alt Text
ApiQueryGlobalAllUsers.php (9 KB)

Event Timeline