Viewing File: /home/omtekel/www/wp-content/upgrade/backup/Api.tar
CheckMatch.php 0000666 00000012027 15133476722 0007267 0 ustar 00 <?php
namespace MediaWiki\Extension\AbuseFilter\Api;
use ApiBase;
use ApiMain;
use ApiResult;
use FormatJson;
use LogEventsList;
use LogicException;
use LogPage;
use MediaWiki\Extension\AbuseFilter\AbuseFilterPermissionManager;
use MediaWiki\Extension\AbuseFilter\Parser\RuleCheckerFactory;
use MediaWiki\Extension\AbuseFilter\Special\SpecialAbuseLog;
use MediaWiki\Extension\AbuseFilter\VariableGenerator\VariableGeneratorFactory;
use MediaWiki\Extension\AbuseFilter\Variables\VariableHolder;
use MediaWiki\Extension\AbuseFilter\Variables\VariablesBlobStore;
use MediaWiki\Revision\RevisionRecord;
use RecentChange;
use Wikimedia\ParamValidator\ParamValidator;
class CheckMatch extends ApiBase {
/** @var RuleCheckerFactory */
private $ruleCheckerFactory;
/** @var AbuseFilterPermissionManager */
private $afPermManager;
/** @var VariablesBlobStore */
private $afVariablesBlobStore;
/** @var VariableGeneratorFactory */
private $afVariableGeneratorFactory;
/**
* @param ApiMain $main
* @param string $action
* @param RuleCheckerFactory $ruleCheckerFactory
* @param AbuseFilterPermissionManager $afPermManager
* @param VariablesBlobStore $afVariablesBlobStore
* @param VariableGeneratorFactory $afVariableGeneratorFactory
*/
public function __construct(
ApiMain $main,
$action,
RuleCheckerFactory $ruleCheckerFactory,
AbuseFilterPermissionManager $afPermManager,
VariablesBlobStore $afVariablesBlobStore,
VariableGeneratorFactory $afVariableGeneratorFactory
) {
parent::__construct( $main, $action );
$this->ruleCheckerFactory = $ruleCheckerFactory;
$this->afPermManager = $afPermManager;
$this->afVariablesBlobStore = $afVariablesBlobStore;
$this->afVariableGeneratorFactory = $afVariableGeneratorFactory;
}
/**
* @inheritDoc
*/
public function execute() {
$performer = $this->getAuthority();
$params = $this->extractRequestParams();
$this->requireOnlyOneParameter( $params, 'vars', 'rcid', 'logid' );
// "Anti-DoS"
if ( !$this->afPermManager->canUseTestTools( $performer ) ) {
$this->dieWithError( 'apierror-abusefilter-canttest', 'permissiondenied' );
}
$vars = null;
if ( $params['vars'] ) {
$pairs = FormatJson::decode( $params['vars'], true );
$vars = VariableHolder::newFromArray( $pairs );
} elseif ( $params['rcid'] ) {
$rc = RecentChange::newFromId( $params['rcid'] );
if ( !$rc ) {
$this->dieWithError( [ 'apierror-nosuchrcid', $params['rcid'] ] );
}
$type = (int)$rc->getAttribute( 'rc_type' );
$deletedValue = $rc->getAttribute( 'rc_deleted' );
if (
(
$type === RC_LOG &&
!LogEventsList::userCanBitfield(
$deletedValue,
LogPage::SUPPRESSED_ACTION | LogPage::SUPPRESSED_USER,
$performer
)
) || (
$type !== RC_LOG &&
!RevisionRecord::userCanBitfield( $deletedValue, RevisionRecord::SUPPRESSED_ALL, $performer )
)
) {
// T223654 - Same check as in AbuseFilterChangesList
$this->dieWithError( 'apierror-permissiondenied-generic', 'deletedrc' );
}
$varGenerator = $this->afVariableGeneratorFactory->newRCGenerator( $rc, $this->getUser() );
$vars = $varGenerator->getVars();
} elseif ( $params['logid'] ) {
$row = $this->getDB()->selectRow(
'abuse_filter_log',
'*',
[ 'afl_id' => $params['logid'] ],
__METHOD__
);
if ( !$row ) {
$this->dieWithError( [ 'apierror-abusefilter-nosuchlogid', $params['logid'] ], 'nosuchlogid' );
}
$visibility = SpecialAbuseLog::getEntryVisibilityForUser( $row, $performer, $this->afPermManager );
if ( $visibility !== SpecialAbuseLog::VISIBILITY_VISIBLE ) {
// T223654 - Same check as in SpecialAbuseLog. Both the visibility of the AbuseLog entry
// and the corresponding revision are checked.
$this->dieWithError( 'apierror-permissiondenied-generic', 'deletedabuselog' );
}
$vars = $this->afVariablesBlobStore->loadVarDump( $row->afl_var_dump );
}
if ( $vars === null ) {
// @codeCoverageIgnoreStart
throw new LogicException( 'Impossible.' );
// @codeCoverageIgnoreEnd
}
$ruleChecker = $this->ruleCheckerFactory->newRuleChecker( $vars );
if ( !$ruleChecker->checkSyntax( $params['filter'] )->isValid() ) {
$this->dieWithError( 'apierror-abusefilter-badsyntax', 'badsyntax' );
}
$result = [
ApiResult::META_BC_BOOLS => [ 'result' ],
'result' => $ruleChecker->checkConditions( $params['filter'] )->getResult(),
];
$this->getResult()->addValue(
null,
$this->getModuleName(),
$result
);
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
public function getAllowedParams() {
return [
'filter' => [
ParamValidator::PARAM_REQUIRED => true,
],
'vars' => null,
'rcid' => [
ParamValidator::PARAM_TYPE => 'integer'
],
'logid' => [
ParamValidator::PARAM_TYPE => 'integer'
],
];
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
protected function getExamplesMessages() {
return [
'action=abusefiltercheckmatch&filter=!("autoconfirmed"%20in%20user_groups)&rcid=15'
=> 'apihelp-abusefiltercheckmatch-example-1',
];
}
}
EvalExpression.php 0000666 00000006262 15133476722 0010250 0 ustar 00 <?php
namespace MediaWiki\Extension\AbuseFilter\Api;
use ApiBase;
use ApiMain;
use ApiResult;
use MediaWiki\Extension\AbuseFilter\AbuseFilterPermissionManager;
use MediaWiki\Extension\AbuseFilter\Parser\RuleCheckerFactory;
use MediaWiki\Extension\AbuseFilter\VariableGenerator\VariableGeneratorFactory;
use MediaWiki\Extension\AbuseFilter\Variables\VariablesFormatter;
use Status;
use Wikimedia\ParamValidator\ParamValidator;
class EvalExpression extends ApiBase {
/** @var RuleCheckerFactory */
private $ruleCheckerFactory;
/** @var AbuseFilterPermissionManager */
private $afPermManager;
/** @var VariableGeneratorFactory */
private $afVariableGeneratorFactory;
/**
* @param ApiMain $main
* @param string $action
* @param RuleCheckerFactory $ruleCheckerFactory
* @param AbuseFilterPermissionManager $afPermManager
* @param VariableGeneratorFactory $afVariableGeneratorFactory
*/
public function __construct(
ApiMain $main,
$action,
RuleCheckerFactory $ruleCheckerFactory,
AbuseFilterPermissionManager $afPermManager,
VariableGeneratorFactory $afVariableGeneratorFactory
) {
parent::__construct( $main, $action );
$this->ruleCheckerFactory = $ruleCheckerFactory;
$this->afPermManager = $afPermManager;
$this->afVariableGeneratorFactory = $afVariableGeneratorFactory;
}
/**
* @inheritDoc
*/
public function execute() {
// "Anti-DoS"
if ( !$this->afPermManager->canUseTestTools( $this->getAuthority() ) ) {
$this->dieWithError( 'apierror-abusefilter-canteval', 'permissiondenied' );
}
$params = $this->extractRequestParams();
$status = $this->evaluateExpression( $params['expression'] );
if ( !$status->isGood() ) {
$this->dieWithError( $status->getErrors()[0] );
} else {
$res = $status->getValue();
$res = $params['prettyprint'] ? VariablesFormatter::formatVar( $res ) : $res;
$this->getResult()->addValue(
null,
$this->getModuleName(),
ApiResult::addMetadataToResultVars( [ 'result' => $res ] )
);
}
}
/**
* @param string $expr
* @return Status
*/
private function evaluateExpression( string $expr ): Status {
$ruleChecker = $this->ruleCheckerFactory->newRuleChecker();
if ( !$ruleChecker->checkSyntax( $expr )->isValid() ) {
return Status::newFatal( 'abusefilter-tools-syntax-error' );
}
// Generic vars are the only ones available
$generator = $this->afVariableGeneratorFactory->newGenerator();
$vars = $generator->addGenericVars()->getVariableHolder();
$ruleChecker->setVariables( $vars );
return Status::newGood( $ruleChecker->evaluateExpression( $expr ) );
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
public function getAllowedParams() {
return [
'expression' => [
ParamValidator::PARAM_REQUIRED => true,
],
'prettyprint' => [
ParamValidator::PARAM_TYPE => 'boolean'
]
];
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
protected function getExamplesMessages() {
return [
'action=abusefilterevalexpression&expression=lcase("FOO")'
=> 'apihelp-abusefilterevalexpression-example-1',
'action=abusefilterevalexpression&expression=lcase("FOO")&prettyprint=1'
=> 'apihelp-abusefilterevalexpression-example-2',
];
}
}
AbuseLogPrivateDetails.php 0000666 00000007237 15133476722 0011646 0 ustar 00 <?php
/**
* 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
*/
namespace MediaWiki\Extension\AbuseFilter\Api;
use ApiBase;
use ApiMain;
use MediaWiki\Extension\AbuseFilter\AbuseFilterPermissionManager;
use MediaWiki\Extension\AbuseFilter\Special\SpecialAbuseLog;
use Wikimedia\ParamValidator\ParamValidator;
/**
* API module to allow accessing private details (the user's IP) from AbuseLog entries
*
* @ingroup API
* @ingroup Extensions
*/
class AbuseLogPrivateDetails extends ApiBase {
/** @var AbuseFilterPermissionManager */
private $afPermManager;
/**
* @param ApiMain $main
* @param string $action
* @param AbuseFilterPermissionManager $afPermManager
*/
public function __construct(
ApiMain $main,
$action,
AbuseFilterPermissionManager $afPermManager
) {
parent::__construct( $main, $action );
$this->afPermManager = $afPermManager;
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
public function mustBePosted() {
return true;
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
public function isWriteMode() {
return true;
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
public function needsToken() {
return 'csrf';
}
/**
* @inheritDoc
*/
public function execute() {
$user = $this->getUser();
if ( !$this->afPermManager->canSeePrivateDetails( $user ) ) {
$this->dieWithError( 'abusefilter-log-cannot-see-privatedetails' );
}
$params = $this->extractRequestParams();
if ( !SpecialAbuseLog::checkPrivateDetailsAccessReason( $params['reason'] ) ) {
// Double check, in case we add some extra validation
$this->dieWithError( 'abusefilter-noreason' );
}
$status = SpecialAbuseLog::getPrivateDetailsRow( $user, $params['logid'] );
if ( !$status->isGood() ) {
$this->dieStatus( $status );
}
$row = $status->getValue();
// Log accessing private details
if ( $this->getConfig()->get( 'AbuseFilterLogPrivateDetailsAccess' ) ) {
SpecialAbuseLog::addPrivateDetailsAccessLogEntry(
$params['logid'],
$params['reason'],
$user
);
}
$result = [
'log-id' => $params['logid'],
'user' => $row->afl_user_text,
'filter-id' => (int)$row->af_id,
'filter-description' => $row->af_public_comments,
'ip-address' => $row->afl_ip !== '' ? $row->afl_ip : null
];
$this->getResult()->addValue( null, $this->getModuleName(), $result );
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
public function getAllowedParams() {
return [
'logid' => [
ParamValidator::PARAM_TYPE => 'integer'
],
'reason' => [
ParamValidator::PARAM_TYPE => 'string',
ParamValidator::PARAM_REQUIRED => $this->getConfig()->get( 'AbuseFilterPrivateDetailsForceReason' ),
]
];
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
protected function getExamplesMessages() {
return [
'action=abuselogprivatedetails&logid=1&reason=example&token=ABC123'
=> 'apihelp-abuselogprivatedetails-example-1'
];
}
}
CheckSyntax.php 0000666 00000005205 15133476722 0007521 0 ustar 00 <?php
namespace MediaWiki\Extension\AbuseFilter\Api;
use ApiBase;
use ApiMain;
use MediaWiki\Extension\AbuseFilter\AbuseFilterPermissionManager;
use MediaWiki\Extension\AbuseFilter\Parser\Exception\UserVisibleException;
use MediaWiki\Extension\AbuseFilter\Parser\RuleCheckerFactory;
use Wikimedia\ParamValidator\ParamValidator;
class CheckSyntax extends ApiBase {
/** @var RuleCheckerFactory */
private $ruleCheckerFactory;
/** @var AbuseFilterPermissionManager */
private $afPermManager;
/**
* @param ApiMain $main
* @param string $action
* @param RuleCheckerFactory $ruleCheckerFactory
* @param AbuseFilterPermissionManager $afPermManager
*/
public function __construct(
ApiMain $main,
$action,
RuleCheckerFactory $ruleCheckerFactory,
AbuseFilterPermissionManager $afPermManager
) {
parent::__construct( $main, $action );
$this->ruleCheckerFactory = $ruleCheckerFactory;
$this->afPermManager = $afPermManager;
}
/**
* @inheritDoc
*/
public function execute() {
// "Anti-DoS"
if ( !$this->afPermManager->canUseTestTools( $this->getAuthority() )
&& !$this->afPermManager->canEdit( $this->getAuthority() )
) {
$this->dieWithError( 'apierror-abusefilter-cantcheck', 'permissiondenied' );
}
$params = $this->extractRequestParams();
$result = $this->ruleCheckerFactory->newRuleChecker()->checkSyntax( $params['filter'] );
$r = [];
$warnings = [];
foreach ( $result->getWarnings() as $warning ) {
$warnings[] = [
'message' => $this->msg( $warning->getMessageObj() )->text(),
'character' => $warning->getPosition()
];
}
if ( $warnings ) {
$r['warnings'] = $warnings;
}
if ( $result->isValid() ) {
// Everything went better than expected :)
$r['status'] = 'ok';
} else {
// TODO: Improve the type here.
/** @var UserVisibleException $excep */
$excep = $result->getException();
'@phan-var UserVisibleException $excep';
$r = [
'status' => 'error',
'message' => $this->msg( $excep->getMessageObj() )->text(),
'character' => $excep->getPosition(),
];
}
$this->getResult()->addValue( null, $this->getModuleName(), $r );
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
public function getAllowedParams() {
return [
'filter' => [
ParamValidator::PARAM_REQUIRED => true,
],
];
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
protected function getExamplesMessages() {
return [
'action=abusefilterchecksyntax&filter="foo"'
=> 'apihelp-abusefilterchecksyntax-example-1',
'action=abusefilterchecksyntax&filter="bar"%20bad_variable'
=> 'apihelp-abusefilterchecksyntax-example-2',
];
}
}
UnblockAutopromote.php 0000666 00000004551 15133476722 0011134 0 ustar 00 <?php
namespace MediaWiki\Extension\AbuseFilter\Api;
use ApiBase;
use ApiMain;
use MediaWiki\Extension\AbuseFilter\BlockAutopromoteStore;
use MediaWiki\ParamValidator\TypeDef\UserDef;
use Wikimedia\ParamValidator\ParamValidator;
class UnblockAutopromote extends ApiBase {
/** @var BlockAutopromoteStore */
private $afBlockAutopromoteStore;
/**
* @param ApiMain $main
* @param string $action
* @param BlockAutopromoteStore $afBlockAutopromoteStore
*/
public function __construct(
ApiMain $main,
$action,
BlockAutopromoteStore $afBlockAutopromoteStore
) {
parent::__construct( $main, $action );
$this->afBlockAutopromoteStore = $afBlockAutopromoteStore;
}
/**
* @inheritDoc
*/
public function execute() {
$this->checkUserRightsAny( 'abusefilter-modify' );
$params = $this->extractRequestParams();
$target = $params['user'];
$block = $this->getAuthority()->getBlock();
if ( $block && $block->isSitewide() ) {
$this->dieBlocked( $block );
}
$msg = $this->msg( 'abusefilter-tools-restoreautopromote' )->inContentLanguage()->text();
$res = $this->afBlockAutopromoteStore->unblockAutopromote( $target, $this->getUser(), $msg );
if ( !$res ) {
$this->dieWithError( [ 'abusefilter-reautoconfirm-none', $target->getName() ], 'notsuspended' );
}
$finalResult = [ 'user' => $target->getName() ];
$this->getResult()->addValue( null, $this->getModuleName(), $finalResult );
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
public function mustBePosted() {
return true;
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
public function isWriteMode() {
return true;
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
public function getAllowedParams() {
return [
'user' => [
ParamValidator::PARAM_TYPE => 'user',
ParamValidator::PARAM_REQUIRED => true,
UserDef::PARAM_RETURN_OBJECT => true,
UserDef::PARAM_ALLOWED_USER_TYPES => [ 'name' ],
],
'token' => null,
];
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
public function needsToken() {
return 'csrf';
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
protected function getExamplesMessages() {
return [
'action=abusefilterunblockautopromote&user=Example&token=123ABC'
=> 'apihelp-abusefilterunblockautopromote-example-1',
];
}
}
QueryAbuseFilters.php 0000666 00000016364 15133476722 0010723 0 ustar 00 <?php
/**
* 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
*/
namespace MediaWiki\Extension\AbuseFilter\Api;
use ApiBase;
use ApiQuery;
use ApiQueryBase;
use MediaWiki\Extension\AbuseFilter\AbuseFilterPermissionManager;
use MediaWiki\Extension\AbuseFilter\AbuseFilterServices;
use MWTimestamp;
use Wikimedia\ParamValidator\ParamValidator;
use Wikimedia\ParamValidator\TypeDef\IntegerDef;
/**
* Query module to list abuse filter details.
*
* @copyright 2009 Alex Z. <mrzmanwiki AT gmail DOT com>
* Based mostly on code by Bryan Tong Minh and Roan Kattouw
*
* @ingroup API
* @ingroup Extensions
*/
class QueryAbuseFilters extends ApiQueryBase {
/** @var AbuseFilterPermissionManager */
private $afPermManager;
/**
* @param ApiQuery $query
* @param string $moduleName
* @param AbuseFilterPermissionManager $afPermManager
*/
public function __construct(
ApiQuery $query,
$moduleName,
AbuseFilterPermissionManager $afPermManager
) {
parent::__construct( $query, $moduleName, 'abf' );
$this->afPermManager = $afPermManager;
}
/**
* @inheritDoc
*/
public function execute() {
$this->checkUserRightsAny( 'abusefilter-view' );
$params = $this->extractRequestParams();
$prop = array_fill_keys( $params['prop'], true );
$fld_id = isset( $prop['id'] );
$fld_desc = isset( $prop['description'] );
$fld_pattern = isset( $prop['pattern'] );
$fld_actions = isset( $prop['actions'] );
$fld_hits = isset( $prop['hits'] );
$fld_comments = isset( $prop['comments'] );
$fld_user = isset( $prop['lasteditor'] );
$fld_time = isset( $prop['lastedittime'] );
$fld_status = isset( $prop['status'] );
$fld_private = isset( $prop['private'] );
$result = $this->getResult();
$this->addTables( 'abuse_filter' );
$this->addFields( 'af_id' );
$this->addFields( 'af_hidden' );
$this->addFieldsIf( 'af_hit_count', $fld_hits );
$this->addFieldsIf( 'af_enabled', $fld_status );
$this->addFieldsIf( 'af_deleted', $fld_status );
$this->addFieldsIf( 'af_public_comments', $fld_desc );
$this->addFieldsIf( 'af_pattern', $fld_pattern );
$this->addFieldsIf( 'af_actions', $fld_actions );
$this->addFieldsIf( 'af_comments', $fld_comments );
if ( $fld_user ) {
$actorQuery = AbuseFilterServices::getActorMigration()->getJoin( 'af_user' );
$this->addTables( $actorQuery['tables'] );
$this->addFields( [ 'af_user_text' => $actorQuery['fields']['af_user_text'] ] );
$this->addJoinConds( $actorQuery['joins'] );
}
$this->addFieldsIf( 'af_timestamp', $fld_time );
$this->addOption( 'LIMIT', $params['limit'] + 1 );
$this->addWhereRange( 'af_id', $params['dir'], $params['startid'], $params['endid'] );
if ( $params['show'] !== null ) {
$show = array_fill_keys( $params['show'], true );
/* Check for conflicting parameters. */
if ( ( isset( $show['enabled'] ) && isset( $show['!enabled'] ) )
|| ( isset( $show['deleted'] ) && isset( $show['!deleted'] ) )
|| ( isset( $show['private'] ) && isset( $show['!private'] ) )
) {
$this->dieWithError( 'apierror-show' );
}
$this->addWhereIf( 'af_enabled = 0', isset( $show['!enabled'] ) );
$this->addWhereIf( 'af_enabled != 0', isset( $show['enabled'] ) );
$this->addWhereIf( 'af_deleted = 0', isset( $show['!deleted'] ) );
$this->addWhereIf( 'af_deleted != 0', isset( $show['deleted'] ) );
$this->addWhereIf( 'af_hidden = 0', isset( $show['!private'] ) );
$this->addWhereIf( 'af_hidden != 0', isset( $show['private'] ) );
}
$res = $this->select( __METHOD__ );
$showhidden = $this->afPermManager->canViewPrivateFilters( $this->getAuthority() );
$count = 0;
foreach ( $res as $row ) {
$filterId = intval( $row->af_id );
if ( ++$count > $params['limit'] ) {
// We've had enough
$this->setContinueEnumParameter( 'startid', $filterId );
break;
}
$entry = [];
if ( $fld_id ) {
$entry['id'] = $filterId;
}
if ( $fld_desc ) {
$entry['description'] = $row->af_public_comments;
}
if ( $fld_pattern && ( !$row->af_hidden || $showhidden ) ) {
$entry['pattern'] = $row->af_pattern;
}
if ( $fld_actions ) {
$entry['actions'] = $row->af_actions;
}
if ( $fld_hits ) {
$entry['hits'] = intval( $row->af_hit_count );
}
if ( $fld_comments && ( !$row->af_hidden || $showhidden ) ) {
$entry['comments'] = $row->af_comments;
}
if ( $fld_user ) {
$entry['lasteditor'] = $row->af_user_text;
}
if ( $fld_time ) {
$ts = new MWTimestamp( $row->af_timestamp );
$entry['lastedittime'] = $ts->getTimestamp( TS_ISO_8601 );
}
if ( $fld_private && $row->af_hidden ) {
$entry['private'] = '';
}
if ( $fld_status ) {
if ( $row->af_enabled ) {
$entry['enabled'] = '';
}
if ( $row->af_deleted ) {
$entry['deleted'] = '';
}
}
if ( $entry ) {
$fit = $result->addValue( [ 'query', $this->getModuleName() ], null, $entry );
if ( !$fit ) {
$this->setContinueEnumParameter( 'startid', $filterId );
break;
}
}
}
$result->addIndexedTagName( [ 'query', $this->getModuleName() ], 'filter' );
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
public function getAllowedParams() {
return [
'startid' => [
ParamValidator::PARAM_TYPE => 'integer'
],
'endid' => [
ParamValidator::PARAM_TYPE => 'integer',
],
'dir' => [
ParamValidator::PARAM_TYPE => [
'older',
'newer'
],
ParamValidator::PARAM_DEFAULT => 'newer',
ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
],
'show' => [
ParamValidator::PARAM_ISMULTI => true,
ParamValidator::PARAM_TYPE => [
'enabled',
'!enabled',
'deleted',
'!deleted',
'private',
'!private',
],
],
'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
],
'prop' => [
ParamValidator::PARAM_DEFAULT => 'id|description|actions|status',
ParamValidator::PARAM_TYPE => [
'id',
'description',
'pattern',
'actions',
'hits',
'comments',
'lasteditor',
'lastedittime',
'status',
'private',
],
ParamValidator::PARAM_ISMULTI => true
]
];
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
protected function getExamplesMessages() {
return [
'action=query&list=abusefilters&abfshow=enabled|!private'
=> 'apihelp-query+abusefilters-example-1',
'action=query&list=abusefilters&abfprop=id|description|pattern'
=> 'apihelp-query+abusefilters-example-2',
];
}
}
QueryAbuseLog.php 0000666 00000031215 15133476722 0010024 0 ustar 00 <?php
/**
* 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
*/
namespace MediaWiki\Extension\AbuseFilter\Api;
use ApiBase;
use ApiQuery;
use ApiQueryBase;
use InvalidArgumentException;
use MediaWiki\Extension\AbuseFilter\AbuseFilterPermissionManager;
use MediaWiki\Extension\AbuseFilter\CentralDBNotAvailableException;
use MediaWiki\Extension\AbuseFilter\Filter\FilterNotFoundException;
use MediaWiki\Extension\AbuseFilter\FilterLookup;
use MediaWiki\Extension\AbuseFilter\GlobalNameUtils;
use MediaWiki\Extension\AbuseFilter\Special\SpecialAbuseLog;
use MediaWiki\Extension\AbuseFilter\Variables\VariablesBlobStore;
use MediaWiki\Extension\AbuseFilter\Variables\VariablesManager;
use MediaWiki\Title\Title;
use MWTimestamp;
use User;
use Wikimedia\IPUtils;
use Wikimedia\ParamValidator\ParamValidator;
use Wikimedia\ParamValidator\TypeDef\IntegerDef;
/**
* Query module to list abuse log entries.
*
* @copyright 2009 Alex Z. <mrzmanwiki AT gmail DOT com>
* Based mostly on code by Bryan Tong Minh and Roan Kattouw
*
* @ingroup API
* @ingroup Extensions
*/
class QueryAbuseLog extends ApiQueryBase {
/** @var FilterLookup */
private $afFilterLookup;
/** @var AbuseFilterPermissionManager */
private $afPermManager;
/** @var VariablesBlobStore */
private $afVariablesBlobStore;
/** @var VariablesManager */
private $afVariablesManager;
/**
* @param ApiQuery $query
* @param string $moduleName
* @param FilterLookup $afFilterLookup
* @param AbuseFilterPermissionManager $afPermManager
* @param VariablesBlobStore $afVariablesBlobStore
* @param VariablesManager $afVariablesManager
*/
public function __construct(
ApiQuery $query,
$moduleName,
FilterLookup $afFilterLookup,
AbuseFilterPermissionManager $afPermManager,
VariablesBlobStore $afVariablesBlobStore,
VariablesManager $afVariablesManager
) {
parent::__construct( $query, $moduleName, 'afl' );
$this->afFilterLookup = $afFilterLookup;
$this->afPermManager = $afPermManager;
$this->afVariablesBlobStore = $afVariablesBlobStore;
$this->afVariablesManager = $afVariablesManager;
}
/**
* @inheritDoc
*/
public function execute() {
$lookup = $this->afFilterLookup;
// Same check as in SpecialAbuseLog
$this->checkUserRightsAny( 'abusefilter-log' );
$performer = $this->getAuthority();
$params = $this->extractRequestParams();
$prop = array_fill_keys( $params['prop'], true );
$fld_ids = isset( $prop['ids'] );
$fld_filter = isset( $prop['filter'] );
$fld_user = isset( $prop['user'] );
$fld_title = isset( $prop['title'] );
$fld_action = isset( $prop['action'] );
$fld_details = isset( $prop['details'] );
$fld_result = isset( $prop['result'] );
$fld_timestamp = isset( $prop['timestamp'] );
$fld_hidden = isset( $prop['hidden'] );
$fld_revid = isset( $prop['revid'] );
$isCentral = $this->getConfig()->get( 'AbuseFilterIsCentral' );
$fld_wiki = $isCentral && isset( $prop['wiki'] );
if ( $fld_details ) {
$this->checkUserRightsAny( 'abusefilter-log-detail' );
}
// Map of [ [ id, global ], ... ]
$searchFilters = [];
// Match permissions for viewing events on private filters to SpecialAbuseLog (bug 42814)
// @todo Avoid code duplication with SpecialAbuseLog::showList, make it so that, if hidden
// filters are specified, we only filter them out instead of failing.
if ( $params['filter'] ) {
if ( !is_array( $params['filter'] ) ) {
$params['filter'] = [ $params['filter'] ];
}
$foundInvalid = false;
foreach ( $params['filter'] as $filter ) {
try {
$searchFilters[] = GlobalNameUtils::splitGlobalName( $filter );
} catch ( InvalidArgumentException $e ) {
$foundInvalid = true;
continue;
}
}
if ( !$this->afPermManager->canViewPrivateFiltersLogs( $performer ) ) {
foreach ( $searchFilters as [ $filterID, $global ] ) {
try {
$isHidden = $lookup->getFilter( $filterID, $global )->isHidden();
} catch ( CentralDBNotAvailableException $_ ) {
// Conservatively assume it's hidden, like in SpecialAbuseLog
$isHidden = true;
} catch ( FilterNotFoundException $_ ) {
$isHidden = false;
$foundInvalid = true;
}
if ( $isHidden ) {
$this->dieWithError(
[ 'apierror-permissiondenied', $this->msg( 'action-abusefilter-log-private' ) ]
);
}
}
}
if ( $foundInvalid ) {
// @todo Tell what the invalid IDs are
$this->addWarning( 'abusefilter-log-invalid-filter' );
}
}
$result = $this->getResult();
$this->addTables( 'abuse_filter_log' );
$this->addFields( 'afl_timestamp' );
$this->addFields( 'afl_rev_id' );
$this->addFields( 'afl_deleted' );
$this->addFields( 'afl_filter_id' );
$this->addFields( 'afl_global' );
$this->addFieldsIf( 'afl_id', $fld_ids );
$this->addFieldsIf( 'afl_user_text', $fld_user );
$this->addFieldsIf( [ 'afl_namespace', 'afl_title' ], $fld_title );
$this->addFieldsIf( 'afl_action', $fld_action );
$this->addFieldsIf( 'afl_var_dump', $fld_details );
$this->addFieldsIf( 'afl_actions', $fld_result );
$this->addFieldsIf( 'afl_wiki', $fld_wiki );
if ( $fld_filter ) {
$this->addTables( 'abuse_filter' );
$this->addFields( 'af_public_comments' );
$this->addJoinConds( [
'abuse_filter' => [
'LEFT JOIN',
[
'af_id=afl_filter_id',
'afl_global' => 0
]
]
] );
}
$this->addOption( 'LIMIT', $params['limit'] + 1 );
$this->addWhereIf( [ 'afl_id' => $params['logid'] ], isset( $params['logid'] ) );
$this->addWhereRange( 'afl_timestamp', $params['dir'], $params['start'], $params['end'] );
if ( isset( $params['user'] ) ) {
$u = User::newFromName( $params['user'] );
if ( $u ) {
// Username normalisation
$params['user'] = $u->getName();
$userId = $u->getId();
} elseif ( IPUtils::isIPAddress( $params['user'] ) ) {
// It's an IP, sanitize it
$params['user'] = IPUtils::sanitizeIP( $params['user'] );
$userId = 0;
}
if ( isset( $userId ) ) {
// Only add the WHERE for user in case it's either a valid user
// (but not necessary an existing one) or an IP.
$this->addWhere(
[
'afl_user' => $userId,
'afl_user_text' => $params['user']
]
);
}
}
$this->addWhereIf( [ 'afl_deleted' => 0 ], !$this->afPermManager->canSeeHiddenLogEntries( $performer ) );
if ( $searchFilters ) {
// @todo Avoid code duplication with SpecialAbuseLog::showList
$filterConds = [ 'local' => [], 'global' => [] ];
foreach ( $searchFilters as $filter ) {
$isGlobal = $filter[1];
$key = $isGlobal ? 'global' : 'local';
$filterConds[$key][] = $filter[0];
}
$conds = [];
if ( $filterConds['local'] ) {
$conds[] = $this->getDB()->makeList(
[ 'afl_global' => 0, 'afl_filter_id' => $filterConds['local'] ],
LIST_AND
);
}
if ( $filterConds['global'] ) {
$conds[] = $this->getDB()->makeList(
[ 'afl_global' => 1, 'afl_filter_id' => $filterConds['global'] ],
LIST_AND
);
}
$conds = $this->getDB()->makeList( $conds, LIST_OR );
$this->addWhere( $conds );
}
if ( isset( $params['wiki'] ) ) {
// 'wiki' won't be set if $wgAbuseFilterIsCentral = false
$this->addWhereIf( [ 'afl_wiki' => $params['wiki'] ], $isCentral );
}
$title = $params['title'];
if ( $title !== null ) {
$titleObj = Title::newFromText( $title );
if ( $titleObj === null ) {
$this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $title ) ] );
}
$this->addWhereFld( 'afl_namespace', $titleObj->getNamespace() );
$this->addWhereFld( 'afl_title', $titleObj->getDBkey() );
}
$res = $this->select( __METHOD__ );
$count = 0;
foreach ( $res as $row ) {
if ( ++$count > $params['limit'] ) {
// We've had enough
$ts = new MWTimestamp( $row->afl_timestamp );
$this->setContinueEnumParameter( 'start', $ts->getTimestamp( TS_ISO_8601 ) );
break;
}
$visibility = SpecialAbuseLog::getEntryVisibilityForUser( $row, $performer, $this->afPermManager );
if ( $visibility !== SpecialAbuseLog::VISIBILITY_VISIBLE ) {
continue;
}
$filterID = $row->afl_filter_id;
$global = $row->afl_global;
$fullName = GlobalNameUtils::buildGlobalName( $filterID, $global );
$isHidden = $lookup->getFilter( $filterID, $global )->isHidden();
$canSeeDetails = $this->afPermManager->canSeeLogDetailsForFilter( $performer, $isHidden );
$entry = [];
if ( $fld_ids ) {
$entry['id'] = intval( $row->afl_id );
$entry['filter_id'] = $canSeeDetails ? $fullName : '';
}
if ( $fld_filter ) {
if ( $global ) {
$entry['filter'] = $lookup->getFilter( $filterID, true )->getName();
} else {
$entry['filter'] = $row->af_public_comments;
}
}
if ( $fld_user ) {
$entry['user'] = $row->afl_user_text;
}
if ( $fld_wiki ) {
$entry['wiki'] = $row->afl_wiki;
}
if ( $fld_title ) {
$title = Title::makeTitle( $row->afl_namespace, $row->afl_title );
ApiQueryBase::addTitleInfo( $entry, $title );
}
if ( $fld_action ) {
$entry['action'] = $row->afl_action;
}
if ( $fld_result ) {
$entry['result'] = $row->afl_actions;
}
if ( $fld_revid && $row->afl_rev_id !== null ) {
$entry['revid'] = $canSeeDetails ? (int)$row->afl_rev_id : '';
}
if ( $fld_timestamp ) {
$ts = new MWTimestamp( $row->afl_timestamp );
$entry['timestamp'] = $ts->getTimestamp( TS_ISO_8601 );
}
if ( $fld_details ) {
$entry['details'] = [];
if ( $canSeeDetails ) {
$vars = $this->afVariablesBlobStore->loadVarDump( $row->afl_var_dump );
$varManager = $this->afVariablesManager;
$entry['details'] = $varManager->exportAllVars( $vars );
}
}
if ( $fld_hidden ) {
$entry['hidden'] = (bool)$row->afl_deleted;
}
if ( $entry ) {
$fit = $result->addValue( [ 'query', $this->getModuleName() ], null, $entry );
if ( !$fit ) {
$ts = new MWTimestamp( $row->afl_timestamp );
$this->setContinueEnumParameter( 'start', $ts->getTimestamp( TS_ISO_8601 ) );
break;
}
}
}
$result->addIndexedTagName( [ 'query', $this->getModuleName() ], 'item' );
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
public function getAllowedParams() {
$params = [
'logid' => [
ParamValidator::PARAM_TYPE => 'integer'
],
'start' => [
ParamValidator::PARAM_TYPE => 'timestamp'
],
'end' => [
ParamValidator::PARAM_TYPE => 'timestamp'
],
'dir' => [
ParamValidator::PARAM_TYPE => [
'newer',
'older'
],
ParamValidator::PARAM_DEFAULT => 'older',
ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
],
'user' => null,
'title' => null,
'filter' => [
ParamValidator::PARAM_TYPE => 'string',
ParamValidator::PARAM_ISMULTI => true,
ApiBase::PARAM_HELP_MSG => [
'apihelp-query+abuselog-param-filter',
GlobalNameUtils::GLOBAL_FILTER_PREFIX
]
],
'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
],
'prop' => [
ParamValidator::PARAM_DEFAULT => 'ids|user|title|action|result|timestamp|hidden|revid',
ParamValidator::PARAM_TYPE => [
'ids',
'filter',
'user',
'title',
'action',
'details',
'result',
'timestamp',
'hidden',
'revid',
],
ParamValidator::PARAM_ISMULTI => true
]
];
if ( $this->getConfig()->get( 'AbuseFilterIsCentral' ) ) {
$params['wiki'] = [
ParamValidator::PARAM_TYPE => 'string',
];
$params['prop'][ParamValidator::PARAM_DEFAULT] .= '|wiki';
$params['prop'][ParamValidator::PARAM_TYPE][] = 'wiki';
$params['filter'][ApiBase::PARAM_HELP_MSG] = 'apihelp-query+abuselog-param-filter-central';
}
return $params;
}
/**
* @codeCoverageIgnore Merely declarative
* @inheritDoc
*/
protected function getExamplesMessages() {
return [
'action=query&list=abuselog'
=> 'apihelp-query+abuselog-example-1',
'action=query&list=abuselog&afltitle=API'
=> 'apihelp-query+abuselog-example-2',
];
}
}
Back to Directory
File Manager