mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Echo
synced 2024-11-12 09:26:05 +00:00
c1365be90d
Change-Id: Ic27240df0744c6025e7b1922d31250377f0a2bc4
165 lines
4.2 KiB
PHP
165 lines
4.2 KiB
PHP
<?php
|
|
|
|
use MediaWiki\Logger\LoggerFactory;
|
|
use MediaWiki\Session\SessionManager;
|
|
|
|
class EchoForeignWikiRequest {
|
|
|
|
/**
|
|
* @param User $user User object
|
|
* @param array $params Request parameters
|
|
* @param array $wikis Wikis to send the request to
|
|
* @param string $wikiParam Parameter name to set to the name of the wiki
|
|
*/
|
|
public function __construct( User $user, array $params, array $wikis, $wikiParam = null ) {
|
|
$this->user = $user;
|
|
$this->params = $params;
|
|
$this->wikis = $wikis;
|
|
$this->wikiParam = $wikiParam;
|
|
}
|
|
|
|
/**
|
|
* Execute the request
|
|
* @return array [ wiki => result ]
|
|
*/
|
|
public function execute() {
|
|
if ( !$this->canUseCentralAuth() ) {
|
|
return array();
|
|
}
|
|
|
|
$reqs = $this->getRequestParams();
|
|
return $this->doRequests( $reqs );
|
|
}
|
|
|
|
protected function getCentralId( $user ) {
|
|
$lookup = CentralIdLookup::factory();
|
|
$id = $lookup->centralIdFromLocalUser( $user, CentralIdLookup::AUDIENCE_RAW );
|
|
return $id;
|
|
}
|
|
|
|
protected function canUseCentralAuth() {
|
|
global $wgFullyInitialised, $wgUser;
|
|
|
|
return $wgFullyInitialised &&
|
|
$wgUser->isSafeToLoad() &&
|
|
$this->user->isSafeToLoad() &&
|
|
SessionManager::getGlobalSession()->getProvider() instanceof CentralAuthSessionProvider &&
|
|
$this->getCentralId( $this->user ) !== 0;
|
|
}
|
|
|
|
/**
|
|
* Returns CentralAuth token, or null on failure.
|
|
*
|
|
* @param User $user
|
|
* @return string|null
|
|
*/
|
|
protected function getCentralAuthToken( User $user ) {
|
|
$context = new RequestContext;
|
|
$context->setRequest( new FauxRequest( array( 'action' => 'centralauthtoken' ) ) );
|
|
$context->setUser( $user );
|
|
|
|
$api = new ApiMain( $context );
|
|
|
|
try {
|
|
$api->execute();
|
|
|
|
return $api->getResult()->getResultData( array( 'centralauthtoken', 'centralauthtoken' ) );
|
|
} catch ( Exception $ex ) {
|
|
LoggerFactory::getInstance( 'Echo' )->debug(
|
|
'Exception when fetching CentralAuth token: wiki: {wiki}, userName: {userName}, userId: {userId}, centralId: {centralId}, exception: {exception}',
|
|
array(
|
|
'wiki' => wfWikiID(),
|
|
'userName' => $user->getName(),
|
|
'userId' => $user->getId(),
|
|
'centralId' => $this->getCentralId( $user ),
|
|
'exception' => $ex,
|
|
)
|
|
);
|
|
|
|
MWExceptionHandler::logException( $ex );
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
protected function getRequestParams() {
|
|
$apis = EchoForeignNotifications::getApiEndpoints( $this->wikis );
|
|
if ( !$apis ) {
|
|
return array();
|
|
}
|
|
|
|
$reqs = array();
|
|
foreach ( $apis as $wiki => $api ) {
|
|
$reqs[$wiki] = array(
|
|
'method' => 'GET',
|
|
'url' => $api['url'],
|
|
'query' => $this->getQueryParams( $wiki ),
|
|
);
|
|
}
|
|
|
|
return $reqs;
|
|
}
|
|
|
|
/**
|
|
* @param string $wiki Wiki name
|
|
* @return array
|
|
*/
|
|
protected function getQueryParams( $wiki ) {
|
|
$extraParams = array();
|
|
if ( $this->wikiParam ) {
|
|
// Only request data from that specific wiki, or they'd all spawn
|
|
// cross-wiki api requests...
|
|
$extraParams[$this->wikiParam] = $wiki;
|
|
}
|
|
|
|
return array(
|
|
'centralauthtoken' => $this->getCentralAuthToken( $this->user ),
|
|
// once all the results are gathered & merged, they'll be output in the
|
|
// user requested format
|
|
// but this is going to be an internal request & we don't want those
|
|
// results in the format the user requested but in a fixed format that
|
|
// we can interpret here
|
|
'format' => 'json',
|
|
) + $extraParams + $this->params;
|
|
}
|
|
|
|
/**
|
|
* @param array $reqs API request params
|
|
* @return array
|
|
* @throws Exception
|
|
*/
|
|
protected function doRequests( array $reqs ) {
|
|
$http = new MultiHttpClient( array() );
|
|
$responses = $http->runMulti( $reqs );
|
|
|
|
$results = array();
|
|
foreach ( $responses as $wiki => $response ) {
|
|
$statusCode = $response['response']['code'];
|
|
|
|
if ( $statusCode >= 200 && $statusCode <= 299 ) {
|
|
$parsed = json_decode( $response['response']['body'], true );
|
|
if ( $parsed ) {
|
|
$results[$wiki] = $parsed;
|
|
}
|
|
}
|
|
|
|
if ( !isset( $results[$wiki] ) ) {
|
|
LoggerFactory::getInstance( 'Echo' )->warning(
|
|
'Failed to fetch API response from {wiki}. Error code {code}',
|
|
array(
|
|
'wiki' => $wiki,
|
|
'code' => $response['response']['code'],
|
|
'response' => $response['response']['body'],
|
|
'request' => $reqs[$wiki],
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
return $results;
|
|
}
|
|
}
|