260 lines
7.3 KiB
PHP
260 lines
7.3 KiB
PHP
<?php
|
|
|
|
/**
|
|
* CheckUser API Query Module
|
|
*/
|
|
class ApiQueryCheckUser extends ApiQueryBase {
|
|
public function __construct( $query, $moduleName ) {
|
|
parent::__construct( $query, $moduleName, 'cu' );
|
|
}
|
|
|
|
public function execute() {
|
|
global $wgCheckUserForceSummary;
|
|
|
|
$db = $this->getDB( DB_SLAVE );
|
|
$params = $this->extractRequestParams();
|
|
|
|
list( $request, $target, $reason, $timecond, $limit, $xff ) = array(
|
|
$params['request'], $params['target'], $params['reason'],
|
|
$params['timecond'], $params['limit'], $params['xff'] );
|
|
|
|
if ( !$this->getUser()->isAllowed( 'checkuser' ) ) {
|
|
$this->dieUsage( 'You need the checkuser right', 'permissionerror' );
|
|
}
|
|
|
|
if ( $wgCheckUserForceSummary && is_null( $reason ) ) {
|
|
$this->dieUsage( 'You must define reason for check', 'missingdata' );
|
|
}
|
|
|
|
$reason = $this->msg( 'checkuser-reason-api', $reason )->inContentLanguage()->text();
|
|
$timeCutoff = strtotime( $timecond ); // absolute time
|
|
if ( !$timeCutoff ) {
|
|
$this->dieUsage( 'You need use correct time limit (like "-2 weeks" or "2 weeks ago")', 'invalidtime' );
|
|
}
|
|
|
|
$this->addTables( 'cu_changes' );
|
|
$this->addOption( 'LIMIT', $limit + 1 );
|
|
$this->addOption( 'ORDER BY', 'cuc_timestamp DESC' );
|
|
$this->addWhere( "cuc_timestamp > " . $db->addQuotes( $db->timestamp( $timeCutoff ) ) );
|
|
|
|
switch ( $request ) {
|
|
case 'userips':
|
|
$user_id = User::idFromName( $target );
|
|
if ( !$user_id ) {
|
|
$this->dieUsage( 'Target user does not exist', 'nosuchuser' );
|
|
}
|
|
|
|
$this->addFields( array( 'cuc_timestamp', 'cuc_ip', 'cuc_xff' ) );
|
|
$this->addWhereFld( 'cuc_user_text', $target );
|
|
$res = $this->select( __METHOD__ );
|
|
$result = $this->getResult();
|
|
|
|
$ips = array();
|
|
foreach ( $res as $row ) {
|
|
$timestamp = wfTimestamp( TS_ISO_8601, $row->cuc_timestamp );
|
|
$ip = strval( $row->cuc_ip );
|
|
|
|
if ( !isset( $ips[$ip] ) ) {
|
|
$ips[$ip]['end'] = $timestamp;
|
|
$ips[$ip]['editcount'] = 1;
|
|
} else {
|
|
$ips[$ip]['start'] = $timestamp;
|
|
$ips[$ip]['editcount']++;
|
|
}
|
|
}
|
|
|
|
$resultIPs = array();
|
|
foreach ( $ips as $ip => $data ) {
|
|
$data['address'] = $ip;
|
|
$resultIPs[] = $data;
|
|
}
|
|
|
|
CheckUser::addLogEntry( 'userips', 'user', $target, $reason, $user_id );
|
|
$result->addValue( array(
|
|
'query', $this->getModuleName() ), 'userips', $resultIPs );
|
|
$result->addIndexedTagName( array(
|
|
'query', $this->getModuleName(), 'userips' ), 'ip' );
|
|
break;
|
|
|
|
case 'edits':
|
|
if ( IP::isIPAddress( $target ) ) {
|
|
$cond = CheckUser::getIpConds( $db, $target, isset( $xff ) );
|
|
if ( !$cond ) {
|
|
$this->dieUsage( 'IP or range is invalid', 'invalidip' );
|
|
}
|
|
$this->addWhere( $cond );
|
|
$log_type = array();
|
|
if ( isset( $xff ) ) {
|
|
$log_type[] = 'ipedits-xff';
|
|
} else {
|
|
$log_type[] = 'ipedits';
|
|
}
|
|
$log_type[] = 'ip' ;
|
|
} else {
|
|
$user_id = User::idFromName( $target );
|
|
if ( !$user_id ) {
|
|
$this->dieUsage( 'Target user does not exist', 'nosuchuser' );
|
|
}
|
|
$this->addWhereFld( 'cuc_user_text', $target );
|
|
$log_type = array( 'useredits', 'user' );
|
|
}
|
|
|
|
$this->addFields( array(
|
|
'cuc_namespace', 'cuc_title', 'cuc_user_text', 'cuc_actiontext',
|
|
'cuc_comment', 'cuc_minor', 'cuc_timestamp', 'cuc_ip', 'cuc_xff', 'cuc_agent'
|
|
) );
|
|
|
|
$res = $this->select( __METHOD__ );
|
|
$result = $this->getResult();
|
|
|
|
$edits = array();
|
|
foreach ( $res as $row ) {
|
|
$edit = array(
|
|
'timestamp' => wfTimestamp( TS_ISO_8601, $row->cuc_timestamp ),
|
|
'ns' => intval( $row->cuc_namespace ),
|
|
'title' => $row->cuc_title,
|
|
'user' => $row->cuc_user_text,
|
|
'ip' => $row->cuc_ip,
|
|
'agent' => $row->cuc_agent,
|
|
);
|
|
if ( $row->cuc_actiontext ) {
|
|
$edit['summary'] = $row->cuc_actiontext;
|
|
} elseif ( $row->cuc_comment ) {
|
|
$edit['summary'] = $row->cuc_comment;
|
|
}
|
|
if ( $row->cuc_minor ) {
|
|
$edit['minor'] = 'm';
|
|
}
|
|
if ( $row->cuc_xff ) {
|
|
$edit['xff'] = $row->cuc_xff;
|
|
}
|
|
$edits[] = $edit;
|
|
}
|
|
|
|
CheckUser::addLogEntry( $log_type[0], $log_type[1],
|
|
$target, $reason, isset( $user_id ) ? $user_id : '0' );
|
|
$result->addValue( array(
|
|
'query', $this->getModuleName() ), 'edits', $edits );
|
|
$result->addIndexedTagName( array(
|
|
'query', $this->getModuleName(), 'edits' ), 'action' );
|
|
break;
|
|
|
|
case 'ipusers':
|
|
if ( IP::isIPAddress( $target ) ) {
|
|
$cond = CheckUser::getIpConds( $db, $target, isset( $xff ) );
|
|
$this->addWhere( $cond );
|
|
$log_type = 'ipusers';
|
|
if ( isset( $xff ) ) {
|
|
$log_type .= '-xff';
|
|
}
|
|
} else {
|
|
$this->dieUsage( 'IP or range is invalid', 'invalidip' );
|
|
}
|
|
|
|
$this->addFields( array(
|
|
'cuc_user_text', 'cuc_timestamp', 'cuc_ip', 'cuc_agent' ) );
|
|
|
|
$res = $this->select( __METHOD__ );
|
|
$result = $this->getResult();
|
|
|
|
$users = array();
|
|
foreach ( $res as $row ) {
|
|
$user = $row->cuc_user_text;
|
|
$ip = $row->cuc_ip;
|
|
$agent = $row->cuc_agent;
|
|
|
|
if ( !isset( $users[$user] ) ) {
|
|
$users[$user]['end'] = wfTimestamp( TS_ISO_8601, $row->cuc_timestamp );
|
|
$users[$user]['editcount'] = 1;
|
|
$users[$user]['ips'][] = $ip;
|
|
$users[$user]['agents'][] = $agent;
|
|
} else {
|
|
$users[$user]['start'] = wfTimestamp( TS_ISO_8601, $row->cuc_timestamp );
|
|
$users[$user]['editcount']++;
|
|
if ( !in_array( $ip, $users[$user]['ips'] ) ) {
|
|
$users[$user]['ips'][] = $ip;
|
|
}
|
|
if ( !in_array( $agent, $users[$user]['agents'] ) ) {
|
|
$users[$user]['agents'][] = $agent;
|
|
}
|
|
}
|
|
}
|
|
|
|
$resultUsers = array();
|
|
foreach ( $users as $userName => $userData ) {
|
|
$userData['name'] = $userName;
|
|
$result->setIndexedTagName( $userData['ips'], 'ip' );
|
|
$result->setIndexedTagName( $userData['agents'], 'agent' );
|
|
|
|
$resultUsers[] = $userData;
|
|
}
|
|
|
|
CheckUser::addLogEntry( $log_type, 'ip', $target, $reason );
|
|
$result->addValue( array(
|
|
'query', $this->getModuleName() ), 'ipusers', $resultUsers );
|
|
$result->addIndexedTagName( array(
|
|
'query', $this->getModuleName(), 'ipusers' ), 'user' );
|
|
break;
|
|
|
|
default:
|
|
$this->dieUsage( 'Invalid request mode', 'invalidmode' );
|
|
}
|
|
}
|
|
|
|
public function mustBePosted() {
|
|
return true;
|
|
}
|
|
|
|
public function isWriteMode() {
|
|
return true;
|
|
}
|
|
|
|
public function getAllowedParams() {
|
|
return array(
|
|
'request' => array(
|
|
ApiBase::PARAM_REQUIRED => true,
|
|
ApiBase::PARAM_TYPE => array(
|
|
'userips',
|
|
'edits',
|
|
'ipusers',
|
|
)
|
|
),
|
|
'target' => array(
|
|
ApiBase::PARAM_REQUIRED => true,
|
|
),
|
|
'reason' => null,
|
|
'limit' => array(
|
|
ApiBase::PARAM_DFLT => 1000,
|
|
ApiBase::PARAM_TYPE => 'limit',
|
|
ApiBase::PARAM_MIN => 1,
|
|
ApiBase::PARAM_MAX => 500,
|
|
ApiBase::PARAM_MAX2 => 5000,
|
|
),
|
|
'timecond' => array(
|
|
ApiBase::PARAM_DFLT => '-2 weeks'
|
|
),
|
|
'xff' => null,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @see ApiBase::getExamplesMessages()
|
|
*/
|
|
protected function getExamplesMessages() {
|
|
return array(
|
|
'action=query&list=checkuser&curequest=userips&cutarget=Jimbo_Wales'
|
|
=> 'apihelp-query+checkuser-example-1',
|
|
'action=query&list=checkuser&curequest=edits&cutarget=127.0.0.1/16&xff=1&cureason=Some_check'
|
|
=> 'apihelp-query+checkuser-example-2',
|
|
);
|
|
}
|
|
|
|
public function getHelpUrls() {
|
|
return 'https://www.mediawiki.org/wiki/Extension:CheckUser#API';
|
|
}
|
|
|
|
public function needsToken() {
|
|
return 'csrf';
|
|
}
|
|
}
|