summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Echo/includes/ForeignWikiRequest.php')
-rw-r--r--Echo/includes/ForeignWikiRequest.php60
1 files changed, 49 insertions, 11 deletions
diff --git a/Echo/includes/ForeignWikiRequest.php b/Echo/includes/ForeignWikiRequest.php
index c79ccdd7..b3daea33 100644
--- a/Echo/includes/ForeignWikiRequest.php
+++ b/Echo/includes/ForeignWikiRequest.php
@@ -6,28 +6,34 @@ use MediaWiki\Session\SessionManager;
class EchoForeignWikiRequest {
/**
- * @param User $user User object
+ * @param User $user
* @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
+ * @param string|null $wikiParam Parameter name to set to the name of the wiki
+ * @param string|null $postToken If set, use POST requests and inject a token of this type;
+ * if null, use GET requests.
*/
- public function __construct( User $user, array $params, array $wikis, $wikiParam = null ) {
+ public function __construct( User $user, array $params, array $wikis, $wikiParam = null, $postToken = null ) {
$this->user = $user;
$this->params = $params;
$this->wikis = $wikis;
$this->wikiParam = $wikiParam;
+ $this->method = $postToken === null ? 'GET' : 'POST';
+ $this->tokenType = $postToken;
+
+ $this->csrfTokens = null;
}
/**
* Execute the request
- * @return array [ wiki => result ]
+ * @return array[] [ wiki => result ]
*/
public function execute() {
if ( !$this->canUseCentralAuth() ) {
return [];
}
- $reqs = $this->getRequestParams();
+ $reqs = $this->getRequestParams( $this->method, [ $this, 'getQueryParams' ] );
return $this->doRequests( $reqs );
}
@@ -66,7 +72,8 @@ class EchoForeignWikiRequest {
return $api->getResult()->getResultData( [ 'centralauthtoken', 'centralauthtoken' ] );
} catch ( Exception $ex ) {
LoggerFactory::getInstance( 'Echo' )->debug(
- 'Exception when fetching CentralAuth token: wiki: {wiki}, userName: {userName}, userId: {userId}, centralId: {centralId}, exception: {exception}',
+ 'Exception when fetching CentralAuth token: wiki: {wiki}, userName: {userName}, ' .
+ 'userId: {userId}, centralId: {centralId}, exception: {exception}',
[
'wiki' => wfWikiID(),
'userName' => $user->getName(),
@@ -83,9 +90,36 @@ class EchoForeignWikiRequest {
}
/**
- * @return array
+ * Get the CSRF token for a given wiki.
+ * This method fetches the tokens for all requested wikis at once and caches the result.
+ *
+ * @param string $wiki Name of the wiki to get a token for
+ * @return string Token
+ */
+ protected function getCsrfToken( $wiki ) {
+ if ( $this->csrfTokens === null ) {
+ $reqs = $this->getRequestParams( 'GET', [
+ 'action' => 'query',
+ 'meta' => 'tokens',
+ 'type' => $this->tokenType,
+ 'format' => 'json',
+ 'centralauthtoken' => $this->getCentralAuthToken( $this->user ),
+ ] );
+ $responses = $this->doRequests( $reqs );
+ foreach ( $responses as $w => $response ) {
+ $this->csrfTokens[$w] = $response['query']['tokens']['csrftoken'];
+ }
+ }
+ return $this->csrfTokens[$wiki];
+ }
+
+ /**
+ * @param string $method 'GET' or 'POST'
+ * @param array|callable $params Associative array of query string / POST parameters,
+ * or a callback that takes a wiki name and returns such an array
+ * @return array[] Array of request parameters to pass to doRequests(), keyed by wiki name
*/
- protected function getRequestParams() {
+ protected function getRequestParams( $method, $params ) {
$apis = EchoForeignNotifications::getApiEndpoints( $this->wikis );
if ( !$apis ) {
return [];
@@ -93,10 +127,11 @@ class EchoForeignWikiRequest {
$reqs = [];
foreach ( $apis as $wiki => $api ) {
+ $queryKey = $method === 'POST' ? 'body' : 'query';
$reqs[$wiki] = [
- 'method' => 'GET',
+ 'method' => $method,
'url' => $api['url'],
- 'query' => $this->getQueryParams( $wiki ),
+ $queryKey => is_callable( $params ) ? call_user_func( $params, $wiki ) : $params
];
}
@@ -114,6 +149,9 @@ class EchoForeignWikiRequest {
// cross-wiki api requests...
$extraParams[$this->wikiParam] = $wiki;
}
+ if ( $this->method === 'POST' ) {
+ $extraParams['token'] = $this->getCsrfToken( $wiki );
+ }
return [
'centralauthtoken' => $this->getCentralAuthToken( $this->user ),
@@ -128,7 +166,7 @@ class EchoForeignWikiRequest {
/**
* @param array $reqs API request params
- * @return array
+ * @return array[]
* @throws Exception
*/
protected function doRequests( array $reqs ) {