http://www.mediawiki.org/wiki/Special:Code/MediaWiki/100165
Revision: 100165 Author: johnduhart Date: 2011-10-18 21:37:56 +0000 (Tue, 18 Oct 2011) Log Message: ----------- Adds API Module by cryptocoryne Bug 31723 Modified Paths: -------------- trunk/extensions/CheckUser/CheckUser.i18n.php trunk/extensions/CheckUser/CheckUser.php trunk/extensions/CheckUser/CheckUser_body.php Added Paths: ----------- trunk/extensions/CheckUser/api/ trunk/extensions/CheckUser/api/ApiQueryCheckUser.php trunk/extensions/CheckUser/api/ApiQueryCheckUserLog.php Modified: trunk/extensions/CheckUser/CheckUser.i18n.php =================================================================== --- trunk/extensions/CheckUser/CheckUser.i18n.php 2011-10-18 21:36:50 UTC (rev 100164) +++ trunk/extensions/CheckUser/CheckUser.i18n.php 2011-10-18 21:37:56 UTC (rev 100165) @@ -27,6 +27,7 @@ 'right-checkuser-log' => 'View the checkuser log', 'grouppage-checkuser' => '{{ns:project}}:Check user', 'checkuser-reason' => 'Reason:', + 'checkuser-reason-api' => 'API:', 'checkuser-showlog' => 'Show log', 'checkuser-log' => 'CheckUser log', 'checkuser-query' => 'Query recent changes', @@ -136,6 +137,7 @@ 'checkuser-reason' => "Field name on CheckUser Special page. See screenshot '[http://www.mediawiki.org/wiki/Extension:CheckUser#Basic_interface Basic CheckUser interface]'. {{Identical|Reason}}", + 'checkuser-reason-api' => 'Prefixes check user query reasons that are made through the API', 'checkuser-showlog' => "Label for link on CheckUser Special page. See screenshot '[http://www.mediawiki.org/wiki/Extension:CheckUser#Basic_interface Basic CheckUser interface]'.", 'checkuser-query' => "Fieldset label. See [http://www.mediawiki.org/wiki/Extension:CheckUser#Basic_interface screenshot titled 'Basic CheckUser interface'].", 'checkuser-target' => '{{Identical|IP address or username}}', Modified: trunk/extensions/CheckUser/CheckUser.php =================================================================== --- trunk/extensions/CheckUser/CheckUser.php 2011-10-18 21:36:50 UTC (rev 100164) +++ trunk/extensions/CheckUser/CheckUser.php 2011-10-18 21:37:56 UTC (rev 100165) @@ -84,3 +84,9 @@ $wgAutoloadClasses['CheckUser'] = dirname( __FILE__ ) . '/CheckUser_body.php'; $wgAutoloadClasses['CheckUserHooks'] = dirname( __FILE__ ) . '/CheckUser.hooks.php'; + +// API modules +$wgAutoloadClasses['ApiQueryCheckUser'] = "$dir/api/ApiQueryCheckUser.php"; +$wgAPIListModules['checkuser'] = 'ApiQueryCheckUser'; +$wgAutoloadClasses['ApiQueryCheckUserLog'] = "$dir/api/ApiQueryCheckUserLog.php"; +$wgAPIListModules['checkuserlog'] = 'ApiQueryCheckUserLog'; \ No newline at end of file Modified: trunk/extensions/CheckUser/CheckUser_body.php =================================================================== --- trunk/extensions/CheckUser/CheckUser_body.php 2011-10-18 21:36:50 UTC (rev 100164) +++ trunk/extensions/CheckUser/CheckUser_body.php 2011-10-18 21:37:56 UTC (rev 100165) @@ -1284,7 +1284,7 @@ * @param string $xfor * @return mixed array/false conditions */ - protected function getIpConds( $db, $ip, $xfor = false ) { + public static function getIpConds( $db, $ip, $xfor = false ) { $type = ( $xfor ) ? 'xff' : 'ip'; // IPv4 CIDR, 16-32 bits $matches = array(); @@ -1452,7 +1452,7 @@ Xml::monthSelector( $encMonth, - 1 ); } - protected function addLogEntry( $logType, $targetType, $target, $reason, $targetID = 0 ) { + public static function addLogEntry( $logType, $targetType, $target, $reason, $targetID = 0 ) { global $wgUser; if ( $targetType == 'ip' ) { Added: trunk/extensions/CheckUser/api/ApiQueryCheckUser.php =================================================================== --- trunk/extensions/CheckUser/api/ApiQueryCheckUser.php (rev 0) +++ trunk/extensions/CheckUser/api/ApiQueryCheckUser.php 2011-10-18 21:37:56 UTC (rev 100165) @@ -0,0 +1,271 @@ +<?php +/** + * CheckUser API Query Module + */ + +class ApiQueryCheckUser extends ApiQueryBase { + public function __construct( $query, $moduleName ) { + parent::__construct( $query, $moduleName, 'cu' ); + } + + public function execute() { + global $wgUser, $wgCheckUserForceSummary; + + $db = $this->getDB( DB_SLAVE ); + $params = $this->extractRequestParams(); + + if( !$wgUser->isAllowed( 'checkuser' ) ) { + $this->dieUsage( 'You need the checkuser right', 'permissionerror' ); + } + + if( $wgCheckUserForceSummary && is_null($params['reason']) ) { + $this->dieUsage( 'You need define reason for check', 'missingdata' ); + } + + $limit = $params['limit']; + $target = $params['target']; + $reason = wfMsgForContent( 'checkuser-reason-api' ) . ' ' . $params['reason']; + $time = wfTimestamp( TS_MW, strtotime('now') - ( strtotime($params['timecond'] ? $params['timecond'] : '2 weeks') - strtotime('now'))); + if( !$time ) { + $this->dieUsage( 'You need use correct time limit (like "2 weeks")', 'invalidtime' ); + } + + $this->addTables( 'cu_changes' ); + $this->addOption( 'LIMIT', $limit + 1 ); + $this->addOption( 'ORDER BY', 'cuc_timestamp DESC' ); + $this->addWhere( "cuc_timestamp > $time" ); + + switch($params['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->addWhere( "cuc_user_text = '$target'" ); + $res = $this->select( __METHOD__ ); + $result = $this->getResult(); + + $ips = array(); + foreach( $res as $row ) { + $timestamp = $row->cuc_timestamp; + $ip = strval($row->cuc_ip); + $xff = $row->cuc_xff; + + if( !isset( $ips[$ip] ) ) { + $ips[$ip]['end'] = $timestamp; + $ips[$ip]['editcount'] = 1; + } else { + $ips[$ip]['start'] = $timestamp; + $ips[$ip]['editcount']++; + } + } + + $count = 0; + foreach( array_keys($ips) as $ip ) { + $ips[$count] = $ips[$ip]; + $ips[$count]['address'] = $ip; + unset($ips[$ip]); + $count++; + } + + CheckUser::addLogEntry('userips', 'user', $target, $reason, $user_id); + $result->addValue( array( 'query', $this->getModuleName() ), 'userips', $ips ); + $result->setIndexedTagName_internal( array( 'query', $this->getModuleName(), 'userips' ), 'ip' ); + break; + + case 'edits': + if( IP::isIPAddress($target) && isset($params['xff']) ) { + $cond = CheckUser::getIpConds($db, $target, true); + if( !$cond ) { + $this->dieUsage( 'IP or range is invalid', 'invalidip' ); + } + $this->addWhere( "$cond" ); + $log_type = array('ipedits-xff', 'ip'); + } elseif ( IP::isIPAddress($target) ) { + $cond = CheckUser::getIpConds($db, $target); + if( !$cond ) { + $this->dieUsage( 'IP or range is invalid', 'invalidip' ); + } + $this->addWhere( "$cond" ); + $log_type = array('ipedits', 'ip'); + } else { + $user_id = User::idFromName( $target ); + if( !$user_id ) { + $this->dieUsage( 'Target user is not exists', 'nosuchuser' ); + } + $this->addWhere( "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(); + $count = 0; + foreach( $res as $row ) { + $edits[$count]['timestamp'] = $row->cuc_timestamp; + $edits[$count]['ns'] = $row->cuc_namespace; + $edits[$count]['title'] = $row->cuc_title; + $edits[$count]['user'] = $row->cuc_user_text; + if( $row->cuc_actiontext ) { + $edits[$count]['summary'] = $row->cuc_actiontext; + } elseif( $row->cuc_comment ) { + $edits[$count]['summary'] = $row->cuc_comment; + } + if( $row->cuc_minor ) { + $edits[$count]['minor'] = 'm'; + } + $edits[$count]['ip'] = $row->cuc_ip; + if( $row->cuc_xff ) { + $edits[$count]['xff'] = $row->cuc_xff; + } + $edits[$count]['agent'] = $row->cuc_agent; + $count++; + } + + CheckUser::addLogEntry($log_type[0], $log_type[1], $target, $reason, $user_id ? $user_id : '0'); + $result->addValue( array( 'query', $this->getModuleName() ), 'edits', $edits ); + $result->setIndexedTagName_internal( array( 'query', $this->getModuleName(), 'edits' ), 'action' ); + break; + + case 'ipusers': + if( IP::isIPAddress($target) && isset($params['xff']) ) { + $cond = CheckUser::getIpConds($db, $target, true); + $this->addWhere( $cond ); + } elseif ( IP::isIPAddress($target) ) { + $cond = CheckUser::getIpConds($db, $target); + $this->addWhere( $cond ); + $log_type = 'ipusers'; + } 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'] = $row->cuc_timestamp; + $users[$user]['editcount'] = 1; + $users[$user]['ips'][] = $ip; + $users[$user]['agents'][] = $agent; + } else { + $users[$user]['start'] = $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; + } + } + + $count = 0; + foreach( array_keys($users) as $user ) { + $users[$count] = $users[$user]; + $users[$count]['name'] = $user; + unset($users[$user]); + + $result->setIndexedTagName( $users[$count]['ips'], 'ip' ); + $result->setIndexedTagName( $users[$count]['agents'], 'agent' ); + + $count++; + } + + CheckUser::addLogEntry($log_type, 'ip', $target, $reason); + $result->addValue( array( 'query', $this->getModuleName() ), 'ipusers', $users ); + $result->setIndexedTagName_internal( 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 => false, + ApiBase::PARAM_TYPE => array( + 'userips', + 'edits', + 'ipusers' + ) + ), + 'target' => array( + ApiBase::PARAM_REQUIRED => false + ), + 'reason' => null, + 'limit' => array( + ApiBase::PARAM_DFLT => 1000, + ApiBase::PARAM_TYPE => 'limit', + ApiBase::PARAM_MIN => 1, + ApiBase::PARAM_MAX => 5000, + ApiBase::PARAM_MAX2 => 5000 + ), + 'timecond' => null + ); + } + + public function getParamDescription() { + return array( + 'request' => array( + 'Type of CheckUser request', + ' userips - get IP of target user', + ' edits - get changes from target IP or range', + ' ipusers - get users from target IP or range', + ), + 'target' => "Username or IP-address/range to perform check", + 'reason' => 'Reason to check', + 'limit' => 'Limit of rows', + 'timecond' => 'Time limit of user data (like "2 weeks")' + ); + } + + public function getDescription() { + return 'Allows check which IPs are used by a given username and which usernames are used by a given IP'; + } + + public function getPossibleErrors() { + return array_merge( parent::getPossibleErrors(), + array( + array( 'nosuchuser' ), + array( 'invalidip' ), + array( 'permissionerror' ), + array( 'invalidmode' ), + array( 'missingdata' ) + ) + ); + } + + public function getExamples() { + return array( + 'api.php?action=query&list=checkuser&curequest=userips&cutarget=Jimbo_Wales', + 'api.php?action=query&list=checkuser&curequest=edits&cutarget=127.0.0.1/16/xff&cureason=Some_check' + ); + } + + public function getHelpUrls() { + return 'http://www.mediawiki.org/wiki/Extension:CheckUser#API'; + } + + public function getVersion() { + return __CLASS__ . ': $Id$'; + } +} \ No newline at end of file Property changes on: trunk/extensions/CheckUser/api/ApiQueryCheckUser.php ___________________________________________________________________ Added: svn:keywords + Id Added: svn:eol-style + native Added: trunk/extensions/CheckUser/api/ApiQueryCheckUserLog.php =================================================================== --- trunk/extensions/CheckUser/api/ApiQueryCheckUserLog.php (rev 0) +++ trunk/extensions/CheckUser/api/ApiQueryCheckUserLog.php 2011-10-18 21:37:56 UTC (rev 100165) @@ -0,0 +1,117 @@ +<?php +/** + * CheckUser API Query Module + */ + +class ApiQueryCheckUserLog extends ApiQueryBase { + public function __construct( $query, $moduleName ) { + parent::__construct( $query, $moduleName, 'cul' ); + } + + public function execute() { + global $wgUser; + + $params = $this->extractRequestParams(); + + if( !$wgUser->isAllowed( 'checkuser-log' ) ) { + $this->dieUsage( 'You need the checkuser-log right', 'permissionerror' ); + } + + $user = $params['user']; + $limit = $params['limit']; + $target = $params['target']; + $from = $params['from']; + $to = $params['to']; + + $this->addTables( 'cu_log' ); + $this->addOption( 'LIMIT', $limit + 1 ); + $this->addOption( 'ORDER BY', 'cul_timestamp DESC' ); + + $this->addFields( array('cul_timestamp', 'cul_user_text', 'cul_reason', 'cul_type', 'cul_target_text') ); + + if( isset($user) ) $this->addWhere( "cul_user_text = '$user'" ); + if( isset($target) ) $this->addWhere( "cul_target_text = '$target'" ); + if( isset($from) && isset($to) ) { + $this->addWhere( "cul_timestamp BETWEEN '$from' AND '$to'" ); + unset($from, $to); + } elseif ( isset($from) ) { + $this->addWhere( "cul_timestamp < $from" ); + } elseif ( isset($to) ) { + $this->addWhere( "cul_timestamp > $to" ); + } + + $res = $this->select( __METHOD__ ); + $result = $this->getResult(); + + $count = 0; + $log = array(); + foreach( $res as $row ) { + $log[$count]['timestamp'] = $row->cul_timestamp; + $log[$count]['checkuser'] = $row->cul_user_text; + $log[$count]['type'] = $row->cul_type; + $log[$count]['reason'] = $row->cul_reason; + $log[$count]['target'] = $row->cul_target_text; + $count++; + } + + $result->addValue( array( 'query', $this->getModuleName() ), 'entries', $log ); + $result->setIndexedTagName_internal( array( 'query', $this->getModuleName(), 'entries' ), 'entry' ); + } + + public function getAllowedParams() { + return array( + 'user' => null, + 'target' => null, + 'limit' => array( + ApiBase::PARAM_DFLT => 10, + ApiBase::PARAM_TYPE => 'limit', + ApiBase::PARAM_MIN => 1, + ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1, + ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2 + ), + 'from' => array( + ApiBase::PARAM_TYPE => 'timestamp' + ), + 'to' => array( + ApiBase::PARAM_TYPE => 'timestamp' + ), + ); + } + + public function getParamDescription() { + return array( + 'user' => 'Username of CheckUser', + 'target' => "Checked user or IP-address/range", + 'limit' => 'Limit of rows', + 'from' => 'The timestamp to start enumerating from', + 'to' => 'The timestamp to end enumerating' + ); + } + + public function getDescription() { + return 'Allows get entries of CheckUser log'; + } + + public function getPossibleErrors() { + return array_merge( parent::getPossibleErrors(), + array( + array( 'permissionerror' ) + ) + ); + } + + public function getExamples() { + return array( + 'api.php?action=query&list=checkuserlog&culuser=WikiSysop&limit=25', + 'api.php?action=query&list=checkuserlog&cultarget=127.0.0.1&culfrom=20111015230000' + ); + } + + public function getHelpUrls() { + return 'http://www.mediawiki.org/wiki/Extension:CheckUser#API'; + } + + public function getVersion() { + return __CLASS__ . ': $Id$'; + } +} \ No newline at end of file Property changes on: trunk/extensions/CheckUser/api/ApiQueryCheckUserLog.php ___________________________________________________________________ Added: svn:keywords + Id Added: svn:eol-style + native _______________________________________________ MediaWiki-CVS mailing list MediaWiki-CVS@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs