1
0
Fork 0

Merge remote-tracking branch 'upstream/2021.12-rc' into api-fixes

This commit is contained in:
Michael 2021-11-30 19:07:24 +00:00
commit 56f8adcb80
152 changed files with 339 additions and 335 deletions

View file

@ -1064,7 +1064,9 @@ function api_fr_photo_create_update($type)
$deny_cid = $_REQUEST['deny_cid' ] ?? null;
$allow_gid = $_REQUEST['allow_gid'] ?? null;
$deny_gid = $_REQUEST['deny_gid' ] ?? null;
$visibility = !$allow_cid && !$deny_cid && !$allow_gid && !$deny_gid;
// Pictures uploaded via API never get posted as a visible status
// See https://github.com/friendica/friendica/issues/10990
$visibility = false;
// do several checks on input parameters
// we do not allow calls without album string

View file

@ -45,5 +45,6 @@ $a->runFrontend(
$dice->create(\Friendica\Core\PConfig\Capability\IManagePersonalConfigValues::class),
$dice->create(\Friendica\Security\Authentication::class),
$dice->create(\Friendica\App\Page::class),
new \Friendica\Util\HTTPInputData($_SERVER),
$start_time
);

View file

@ -40,10 +40,10 @@ use Friendica\Model\Profile;
use Friendica\Module\Special\HTTPException as ModuleHTTPException;
use Friendica\Network\HTTPException;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\HTTPInputData;
use Friendica\Util\HTTPSignature;
use Friendica\Util\Profiler;
use Friendica\Util\Strings;
use GuzzleHttp\Psr7\Response;
use Psr\Log\LoggerInterface;
/**
@ -562,13 +562,15 @@ class App
*
* @param App\Router $router
* @param IManagePersonalConfigValues $pconfig
* @param Authentication $auth The Authentication backend of the node
* @param App\Page $page The Friendica page printing container
* @param Authentication $auth The Authentication backend of the node
* @param App\Page $page The Friendica page printing container
* @param HTTPInputData $httpInput A library for processing PHP input streams
* @param float $start_time The start time of the overall script execution
*
* @throws HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
public function runFrontend(App\Router $router, IManagePersonalConfigValues $pconfig, Authentication $auth, App\Page $page, float $start_time)
public function runFrontend(App\Router $router, IManagePersonalConfigValues $pconfig, Authentication $auth, App\Page $page, HTTPInputData $httpInput, float $start_time)
{
$this->profiler->set($start_time, 'start');
$this->profiler->set(microtime(true), 'classinit');
@ -702,8 +704,12 @@ class App
$module = $router->getModule();
}
// Processes data from GET requests
$httpinput = $httpInput->process();
$input = array_merge($httpinput['variables'], $httpinput['files'], $request ?? $_REQUEST);
// Let the module run it's internal process (init, get, post, ...)
$response = $module->run($_POST, $_REQUEST);
$response = $module->run($input);
if ($response->getHeaderLine(ICanCreateResponses::X_HEADER) === ICanCreateResponses::TYPE_HTML) {
$page->run($this, $this->baseURL, $this->args, $this->mode, $response, $this->l10n, $this->profiler, $this->config, $pconfig);
} else {

View file

@ -128,8 +128,10 @@ abstract class BaseModule implements ICanHandleRequests
*
* Extend this method if the module is supposed to process DELETE requests.
* Doesn't display any content
*
* @param string[] $request The $_REQUEST content
*/
protected function delete()
protected function delete(array $request = [])
{
}
@ -138,8 +140,10 @@ abstract class BaseModule implements ICanHandleRequests
*
* Extend this method if the module is supposed to process PATCH requests.
* Doesn't display any content
*
* @param string[] $request The $_REQUEST content
*/
protected function patch()
protected function patch(array $request = [])
{
}
@ -150,10 +154,9 @@ abstract class BaseModule implements ICanHandleRequests
* Doesn't display any content
*
* @param string[] $request The $_REQUEST content
* @param string[] $post The $_POST content
*
*/
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
// $this->baseUrl->redirect('module');
}
@ -163,15 +166,17 @@ abstract class BaseModule implements ICanHandleRequests
*
* Extend this method if the module is supposed to process PUT requests.
* Doesn't display any content
*
* @param string[] $request The $_REQUEST content
*/
protected function put()
protected function put(array $request = [])
{
}
/**
* {@inheritDoc}
*/
public function run(array $post = [], array $request = []): ResponseInterface
public function run(array $request = []): ResponseInterface
{
// @see https://github.com/tootsuite/mastodon/blob/c3aef491d66aec743a3a53e934a494f653745b61/config/initializers/cors.rb
if (substr($request['pagename'] ?? '', 0, 12) == '.well-known/') {
@ -208,17 +213,17 @@ abstract class BaseModule implements ICanHandleRequests
switch ($this->server['REQUEST_METHOD'] ?? Router::GET) {
case Router::DELETE:
$this->delete();
$this->delete($request);
break;
case Router::PATCH:
$this->patch();
$this->patch($request);
break;
case Router::POST:
Core\Hook::callAll($this->args->getModuleName() . '_mod_post', $post);
$this->post($request, $post);
Core\Hook::callAll($this->args->getModuleName() . '_mod_post', $request);
$this->post($request);
break;
case Router::PUT:
$this->put();
$this->put($request);
break;
}
@ -231,7 +236,7 @@ abstract class BaseModule implements ICanHandleRequests
$arr = ['content' => ''];
Hook::callAll(static::class . '_mod_content', $arr);
$this->response->addContent($arr['content']);
$this->response->addContent($this->content($_REQUEST));
$this->response->addContent($this->content($request));
} catch (HTTPException $e) {
$this->response->addContent((new ModuleHTTPException())->content($e));
} finally {
@ -241,6 +246,48 @@ abstract class BaseModule implements ICanHandleRequests
return $this->response->generate();
}
/**
* Checks request inputs and sets default parameters
*
* @param array $defaults Associative array of expected request keys and their default typed value. A null
* value will remove the request key from the resulting value array.
* @param array $input Custom REQUEST array, superglobal instead
*
* @return array Request data
*/
protected function checkDefaults(array $defaults, array $input): array
{
$request = [];
foreach ($defaults as $parameter => $defaultvalue) {
if (is_string($defaultvalue)) {
$request[$parameter] = $input[$parameter] ?? $defaultvalue;
} elseif (is_int($defaultvalue)) {
$request[$parameter] = (int)($input[$parameter] ?? $defaultvalue);
} elseif (is_float($defaultvalue)) {
$request[$parameter] = (float)($input[$parameter] ?? $defaultvalue);
} elseif (is_array($defaultvalue)) {
$request[$parameter] = $input[$parameter] ?? [];
} elseif (is_bool($defaultvalue)) {
$request[$parameter] = in_array(strtolower($input[$parameter] ?? ''), ['true', '1']);
} else {
$this->logger->notice('Unhandled default value type', ['parameter' => $parameter, 'type' => gettype($defaultvalue)]);
}
}
foreach ($input ?? [] as $parameter => $value) {
if ($parameter == 'pagename') {
continue;
}
if (!in_array($parameter, array_keys($defaults))) {
$this->logger->notice('Unhandled request field', ['parameter' => $parameter, 'value' => $value, 'command' => $this->args->getCommand()]);
}
}
$this->logger->debug('Got request parameters', ['request' => $request, 'command' => $this->args->getCommand()]);
return $request;
}
/*
* Functions used to protect against Cross-Site Request Forgery
* The security token has to base on at least one value that an attacker can't know - here it's the session ID and the private key.

View file

@ -11,12 +11,11 @@ use Psr\Http\Message\ResponseInterface;
interface ICanHandleRequests
{
/**
* @param array $post The $_POST content (in case of POST)
* @param array $request The $_REQUEST content (in case of GET, POST)
* @param array $request The $_REQUEST content (including content from the PHP input stream)
*
* @return ResponseInterface responding to the request handling
*
* @throws HTTPException\InternalServerErrorException
*/
public function run(array $post = [], array $request = []): ResponseInterface;
public function run(array $request = []): ResponseInterface;
}

View file

@ -109,7 +109,7 @@ class Introduction extends BaseRepository
{
try {
$BaseCollection = parent::_selectByBoundaries(
['`uid = ?` AND NOT `ignore`',$uid],
['`uid` = ? AND NOT `ignore`',$uid],
['order' => ['id' => 'DESC']],
$min_id, $max_id, $limit);
} catch (\Exception $e) {

View file

@ -73,9 +73,9 @@ class LegacyModule extends BaseModule
return $this->runModuleFunction('content');
}
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
parent::post($post);
parent::post($request);
$this->runModuleFunction('post');
}

View file

@ -30,7 +30,7 @@ use Friendica\Util\Strings;
class Details extends BaseAdmin
{
public function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAdminAccess();

View file

@ -32,7 +32,7 @@ use Friendica\Util\Network;
class Contact extends BaseAdmin
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAdminAccess();

View file

@ -32,7 +32,7 @@ use GuzzleHttp\Psr7\Uri;
class Add extends BaseAdmin
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAdminAccess();

View file

@ -27,7 +27,7 @@ use Friendica\Module\BaseAdmin;
class Index extends BaseAdmin
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAdminAccess();

View file

@ -28,7 +28,7 @@ use Friendica\Module\BaseAdmin;
class Features extends BaseAdmin
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAdminAccess();

View file

@ -25,11 +25,10 @@ use Friendica\Core\Renderer;
use Friendica\DI;
use Friendica\Model\Item;
use Friendica\Module\BaseAdmin;
use Friendica\Util\Strings;
class Delete extends BaseAdmin
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAdminAccess();

View file

@ -24,12 +24,11 @@ namespace Friendica\Module\Admin\Logs;
use Friendica\Core\Renderer;
use Friendica\DI;
use Friendica\Module\BaseAdmin;
use Friendica\Util\Strings;
use Psr\Log\LogLevel;
class Settings extends BaseAdmin
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAdminAccess();

View file

@ -43,7 +43,7 @@ require_once __DIR__ . '/../../../boot.php';
class Site extends BaseAdmin
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAdminAccess();

View file

@ -31,7 +31,7 @@ use Friendica\Util\Strings;
class Storage extends BaseAdmin
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAdminAccess();

View file

@ -50,7 +50,7 @@ class Embed extends BaseAdmin
}
}
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAdminAccess();

View file

@ -45,7 +45,7 @@ class Tos extends BaseAdmin
$this->config = $config;
}
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAdminAccess();

View file

@ -30,7 +30,7 @@ use Friendica\Module\Admin\BaseUsers;
class Active extends BaseUsers
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAdminAccess();

View file

@ -31,7 +31,7 @@ use Friendica\Util\Temporal;
class Blocked extends BaseUsers
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAdminAccess();

View file

@ -28,7 +28,7 @@ use Friendica\Module\Admin\BaseUsers;
class Create extends BaseUsers
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAdminAccess();

View file

@ -33,7 +33,7 @@ use Friendica\Util\Temporal;
class Deleted extends BaseUsers
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAdminAccess();

View file

@ -30,7 +30,7 @@ use Friendica\Module\Admin\BaseUsers;
class Index extends BaseUsers
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAdminAccess();

View file

@ -33,7 +33,7 @@ use Friendica\Util\Temporal;
class Pending extends BaseUsers
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAdminAccess();

View file

@ -8,7 +8,6 @@ use Friendica\Core\L10n;
use Friendica\Module\Response;
use Friendica\Util\Arrays;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\HTTPInputData;
use Friendica\Util\XML;
use Psr\Log\LoggerInterface;
use Friendica\Factory\Api\Twitter\User as TwitterUser;
@ -226,11 +225,12 @@ class ApiResponse extends Response
* Quit execution with the message that the endpoint isn't implemented
*
* @param string $method
* @param array $request (optional) The request content of the current call for later analysis
*
* @return void
* @throws \Exception
*/
public function unsupported(string $method = 'all')
public function unsupported(string $method = 'all', array $request = [])
{
$path = $this->args->getQueryString();
$this->logger->info('Unimplemented API call',
@ -238,7 +238,7 @@ class ApiResponse extends Response
'method' => $method,
'path' => $path,
'agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
'request' => HTTPInputData::process()
'request' => $request,
]);
$error = $this->l10n->t('API endpoint %s %s is not implemented', strtoupper($method), $path);
$error_description = $this->l10n->t('The API endpoint is currently not implemented but might be in the future.');

View file

@ -45,7 +45,7 @@ class Activity extends BaseApi
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'id' => 0, // Id of the post
], $request);

View file

@ -35,7 +35,7 @@ class Setseen extends BaseApi
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'id' => 0, // Id of the direct message
], $request);

View file

@ -38,7 +38,7 @@ class Index extends BaseApi
self::checkAllowedScope(self::SCOPE_READ);
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'since_id' => 0,
'count' => 0,
], $request);

View file

@ -37,7 +37,7 @@ class Delete extends BaseApi
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'gid' => 0,
'name' => ''
], $request);

View file

@ -22,7 +22,6 @@
namespace Friendica\Module\Api\Friendica\Group;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Group;
use Friendica\Module\BaseApi;
@ -84,6 +83,6 @@ class Update extends BaseApi
// return success message incl. missing users in array
$status = ($erroraddinguser ? 'missing user' : 'ok');
$success = ['success' => true, 'gid' => $gid, 'name' => $name, 'status' => $status, 'wrong users' => $errorusers];
DI::apiResponse()->exit('group_update', ['$result' => $success], $this->parameters['extension'] ?? null);
$this->response->exit('group_update', ['$result' => $success], $this->parameters['extension'] ?? null);
}
}

View file

@ -32,12 +32,12 @@ require_once __DIR__ . '/../../../../include/api.php';
*/
class Index extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
}
protected function delete()
protected function delete(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
}

View file

@ -70,13 +70,13 @@ class Seen extends BaseApi
// we found the item, return it to the user
$ret = [DI::twitterStatus()->createFromUriId($item['uri-id'], $item['uid'], $include_entities)->toArray()];
$data = ['status' => $ret];
DI::apiResponse()->exit('statuses', $data, $this->parameters['extension'] ?? null);
$this->response->exit('statuses', $data, $this->parameters['extension'] ?? null);
return;
}
// the item can't be found, but we set the notification as seen, so we count this as a success
}
DI::apiResponse()->exit('statuses', ['result' => 'success'], $this->parameters['extension'] ?? null);
$this->response->exit('statuses', ['result' => 'success'], $this->parameters['extension'] ?? null);
} catch (NotFoundException $e) {
throw new BadRequestException('Invalid argument', $e);
} catch (Exception $e) {

View file

@ -36,7 +36,7 @@ class Delete extends BaseApi
{
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'photo_id' => '', // Photo id
], $request);

View file

@ -39,7 +39,7 @@ class Delete extends BaseApi
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'album' => '', // Album name
], $request);

View file

@ -37,7 +37,7 @@ class Update extends BaseApi
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'album' => '', // Current album name
'album_new' => '', // New album name
], $request);

View file

@ -90,6 +90,6 @@ class Conversation extends BaseApi
}
DBA::close($statuses);
DI::apiResponse()->exit('statuses', ['status' => $ret], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
$this->response->exit('statuses', ['status' => $ret], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
}
}

View file

@ -32,7 +32,7 @@ use Friendica\Module\BaseApi;
*/
class Block extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_FOLLOW);
$uid = self::getCurrentUserID();

View file

@ -31,7 +31,7 @@ use Friendica\Module\BaseApi;
*/
class Follow extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_FOLLOW);
$uid = self::getCurrentUserID();

View file

@ -48,7 +48,7 @@ class Followers extends BaseApi
DI::mstdnError()->RecordNotFound();
}
$request = self::getRequest([
$request = $this->getRequest([
'max_id' => 0, // Return results older than this id
'since_id' => 0, // Return results newer than this id
'min_id' => 0, // Return results immediately newer than id

View file

@ -48,7 +48,7 @@ class Following extends BaseApi
DI::mstdnError()->RecordNotFound();
}
$request = self::getRequest([
$request = $this->getRequest([
'max_id' => 0, // Return results older than this id
'since_id' => 0, // Return results newer than this id
'min_id' => 0, // Return results immediately newer than id

View file

@ -31,7 +31,7 @@ use Friendica\Module\BaseApi;
*/
class Mute extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_FOLLOW);
$uid = self::getCurrentUserID();

View file

@ -32,7 +32,7 @@ use Friendica\Module\BaseApi;
*/
class Note extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();
@ -41,7 +41,7 @@ class Note extends BaseApi
DI::mstdnError()->UnprocessableEntity();
}
$request = self::getRequest([
$request = $this->getRequest([
'comment' => '',
], $request);

View file

@ -39,7 +39,7 @@ class Relationships extends BaseApi
self::checkAllowedScope(self::SCOPE_READ);
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'id' => [],
], $request);

View file

@ -42,7 +42,7 @@ class Search extends BaseApi
self::checkAllowedScope(self::SCOPE_READ);
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'q' => '', // What to search for
'limit' => 40, // Maximum number of results. Defaults to 40.
'resolve' => false, // Attempt WebFinger lookup. Defaults to false. Use this when q is an exact address.

View file

@ -52,7 +52,7 @@ class Statuses extends BaseApi
DI::mstdnError()->RecordNotFound();
}
$request = self::getRequest([
$request = $this->getRequest([
'only_media' => false, // Show only statuses with media attached? Defaults to false.
'max_id' => 0, // Return results older than this id
'since_id' => 0, // Return results newer than this id

View file

@ -31,7 +31,7 @@ use Friendica\Module\BaseApi;
*/
class Unblock extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_FOLLOW);
$uid = self::getCurrentUserID();

View file

@ -31,7 +31,7 @@ use Friendica\Module\BaseApi;
*/
class Unfollow extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_FOLLOW);
$uid = self::getCurrentUserID();

View file

@ -31,7 +31,7 @@ use Friendica\Module\BaseApi;
*/
class Unmute extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_FOLLOW);
$uid = self::getCurrentUserID();

View file

@ -24,22 +24,19 @@ namespace Friendica\Module\Api\Mastodon\Accounts;
use Friendica\App\Router;
use Friendica\Core\Logger;
use Friendica\Module\BaseApi;
use Friendica\Util\HTTPInputData;
/**
* @see https://docs.joinmastodon.org/methods/accounts/
*/
class UpdateCredentials extends BaseApi
{
protected function patch()
protected function patch(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();
$data = HTTPInputData::process();
Logger::info('Patch data', ['data' => $request]);
Logger::info('Patch data', ['data' => $data]);
$this->response->unsupported(Router::PATCH);
$this->response->unsupported(Router::PATCH, $request);
}
}

View file

@ -35,9 +35,9 @@ class Apps extends BaseApi
/**
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
$request = self::getRequest([
$request = $this->getRequest([
'client_name' => '',
'redirect_uris' => '',
'scopes' => 'read',

View file

@ -48,7 +48,7 @@ class Blocks extends BaseApi
DI::mstdnError()->RecordNotFound();
}
$request = self::getRequest([
$request = $this->getRequest([
'max_id' => 0, // Return results older than this id
'since_id' => 0, // Return results newer than this id
'min_id' => 0, // Return results immediately newer than id

View file

@ -41,7 +41,7 @@ class Bookmarks extends BaseApi
self::checkAllowedScope(self::SCOPE_READ);
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'limit' => 20, // Maximum number of results to return. Defaults to 20.
'max_id' => 0, // Return results older than id
'since_id' => 0, // Return results newer than id

View file

@ -31,7 +31,7 @@ use Friendica\Module\BaseApi;
*/
class Conversations extends BaseApi
{
protected function delete()
protected function delete(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();
@ -54,7 +54,7 @@ class Conversations extends BaseApi
self::checkAllowedScope(self::SCOPE_READ);
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'limit' => 20, // Maximum number of results. Defaults to 20. Max 40.
'max_id' => 0, // Return results older than this ID. Use HTTP Link header to paginate.
'since_id' => 0, // Return results newer than this ID. Use HTTP Link header to paginate.

View file

@ -31,7 +31,7 @@ use Friendica\Module\BaseApi;
*/
class Read extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();

View file

@ -41,7 +41,7 @@ class Directory extends BaseApi
*/
protected function rawContent(array $request = [])
{
$request = self::getRequest([
$request = $this->getRequest([
'offset' => 0, // How many accounts to skip before returning results. Default 0.
'limit' => 40, // How many accounts to load. Default 40.
'order' => 'active', // active to sort by most recently posted statuses (default) or new to sort by most recently created profiles.

View file

@ -42,7 +42,7 @@ class Favourited extends BaseApi
self::checkAllowedScope(self::SCOPE_READ);
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'limit' => 20, // Maximum number of results to return. Defaults to 20.
'min_id' => 0, // Return results immediately newer than id
'max_id' => 0, // Return results older than id

View file

@ -31,11 +31,11 @@ use Friendica\Module\BaseApi;
*/
class Filters extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$this->response->unsupported(Router::POST);
$this->response->unsupported(Router::POST, $request);
}
/**

View file

@ -42,7 +42,7 @@ class FollowRequests extends BaseApi
* @see https://docs.joinmastodon.org/methods/accounts/follow_requests#accept-follow
* @see https://docs.joinmastodon.org/methods/accounts/follow_requests#reject-follow
*/
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_FOLLOW);
$uid = self::getCurrentUserID();
@ -87,7 +87,7 @@ class FollowRequests extends BaseApi
self::checkAllowedScope(self::SCOPE_READ);
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'min_id' => 0,
'max_id' => 0,
'limit' => 40, // Maximum number of results to return. Defaults to 40. Paginate using the HTTP Link header.

View file

@ -31,7 +31,7 @@ use Friendica\Model\Group;
*/
class Lists extends BaseApi
{
protected function delete()
protected function delete(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();
@ -51,12 +51,12 @@ class Lists extends BaseApi
System::jsonExit([]);
}
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'title' => '',
], $request);
@ -74,9 +74,9 @@ class Lists extends BaseApi
System::jsonExit(DI::mstdnList()->createFromGroupId($id));
}
public function put()
public function put(array $request = [])
{
$request = self::getRequest([
$request = $this->getRequest([
'title' => '', // The title of the list to be updated.
'replies_policy' => '', // One of: "followed", "list", or "none".
]);

View file

@ -34,14 +34,14 @@ use Friendica\Module\BaseApi;
*/
class Accounts extends BaseApi
{
protected function delete()
protected function delete(array $request = [])
{
$this->response->unsupported(Router::DELETE);
$this->response->unsupported(Router::DELETE, $request);
}
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
$this->response->unsupported(Router::POST);
$this->response->unsupported(Router::POST, $request);
}
/**
@ -61,7 +61,7 @@ class Accounts extends BaseApi
DI::mstdnError()->RecordNotFound();
}
$request = self::getRequest([
$request = $this->getRequest([
'max_id' => 0, // Return results older than this id
'since_id' => 0, // Return results newer than this id
'min_id' => 0, // Return results immediately newer than id

View file

@ -31,11 +31,11 @@ use Friendica\Module\BaseApi;
*/
class Markers extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$this->response->unsupported(Router::POST);
$this->response->unsupported(Router::POST, $request);
}
/**

View file

@ -32,7 +32,7 @@ use Friendica\Module\BaseApi;
*/
class Media extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();
@ -53,12 +53,12 @@ class Media extends BaseApi
System::jsonExit(DI::mstdnAttachment()->createFromPhoto($media['id']));
}
public function put()
public function put(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'file' => [], // The file to be attached, using multipart form data.
'thumbnail' => [], // The custom thumbnail of the media to be attached, using multipart form data.
'description' => '', // A plain-text description of the media, for accessibility purposes.

View file

@ -48,7 +48,7 @@ class Mutes extends BaseApi
DI::mstdnError()->RecordNotFound();
}
$request = self::getRequest([
$request = $this->getRequest([
'max_id' => 0, // Return results older than this id
'since_id' => 0, // Return results newer than this id
'min_id' => 0, // Return results immediately newer than id

View file

@ -55,7 +55,7 @@ class Notifications extends BaseApi
}
}
$request = self::getRequest([
$request = $this->getRequest([
'max_id' => 0, // Return results older than this ID
'since_id' => 0, // Return results newer than this ID
'min_id' => 0, // Return results immediately newer than this ID

View file

@ -30,7 +30,7 @@ use Friendica\Module\BaseApi;
*/
class Clear extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();

View file

@ -32,7 +32,7 @@ use Friendica\Network\HTTPException\ForbiddenException;
*/
class Dismiss extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();

View file

@ -33,13 +33,13 @@ use Friendica\Object\Api\Mastodon\Notification;
*/
class PushSubscription extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_PUSH);
$uid = self::getCurrentUserID();
$application = self::getCurrentApplication();
$request = self::getRequest([
$request = $this->getRequest([
'subscription' => [],
'data' => [],
], $request);
@ -66,13 +66,13 @@ class PushSubscription extends BaseApi
return DI::mstdnSubscription()->createForApplicationIdAndUserId($application['id'], $uid)->toArray();
}
public function put()
public function put(array $request = [])
{
self::checkAllowedScope(self::SCOPE_PUSH);
$uid = self::getCurrentUserID();
$application = self::getCurrentApplication();
$request = self::getRequest([
$request = $this->getRequest([
'data' => [],
]);
@ -99,7 +99,7 @@ class PushSubscription extends BaseApi
return DI::mstdnSubscription()->createForApplicationIdAndUserId($application['id'], $uid)->toArray();
}
protected function delete()
protected function delete(array $request = [])
{
self::checkAllowedScope(self::SCOPE_PUSH);
$uid = self::getCurrentUserID();

View file

@ -33,15 +33,15 @@ use Friendica\Module\BaseApi;
*/
class ScheduledStatuses extends BaseApi
{
public function put()
public function put(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();
$this->response->unsupported(Router::PUT);
$this->response->unsupported(Router::PUT, $request);
}
protected function delete()
protected function delete(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();
@ -71,7 +71,7 @@ class ScheduledStatuses extends BaseApi
System::jsonExit(DI::mstdnScheduledStatus()->createFromDelayedPostId($this->parameters['id'], $uid)->toArray());
}
$request = self::getRequest([
$request = $this->getRequest([
'limit' => 20, // Max number of results to return. Defaults to 20.
'max_id' => 0, // Return results older than ID
'since_id' => 0, // Return results newer than ID

View file

@ -45,7 +45,7 @@ class Search extends BaseApi
self::checkAllowedScope(self::SCOPE_READ);
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'account_id' => 0, // If provided, statuses returned will be authored only by this account
'max_id' => 0, // Return results older than this id
'min_id' => 0, // Return results immediately newer than this id

View file

@ -41,12 +41,12 @@ use Friendica\Util\Images;
*/
class Statuses extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'status' => '', // Text content of the status. If media_ids is provided, this becomes optional. Attaching a poll is optional while status is provided.
'media_ids' => [], // Array of Attachment ids to be attached as media. If provided, status becomes optional, and poll cannot be used.
'poll' => [], // Poll data. If provided, media_ids cannot be used, and poll[expires_in] must be provided.
@ -207,7 +207,7 @@ class Statuses extends BaseApi
DI::mstdnError()->InternalError();
}
protected function delete()
protected function delete(array $request = [])
{
self::checkAllowedScope(self::SCOPE_READ);
$uid = self::getCurrentUserID();

View file

@ -33,7 +33,7 @@ use Friendica\Module\BaseApi;
*/
class Bookmark extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();

View file

@ -43,7 +43,7 @@ class Context extends BaseApi
DI::mstdnError()->UnprocessableEntity();
}
$request = self::getRequest([
$request = $this->getRequest([
'limit' => 40, // Maximum number of results to return. Defaults to 40.
], $request);

View file

@ -33,7 +33,7 @@ use Friendica\Module\BaseApi;
*/
class Favourite extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();

View file

@ -32,7 +32,7 @@ use Friendica\Module\BaseApi;
*/
class Mute extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();

View file

@ -32,7 +32,7 @@ use Friendica\Module\BaseApi;
*/
class Pin extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();

View file

@ -35,7 +35,7 @@ use Friendica\Module\BaseApi;
*/
class Reblog extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();

View file

@ -33,7 +33,7 @@ use Friendica\Module\BaseApi;
*/
class Unbookmark extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();

View file

@ -33,7 +33,7 @@ use Friendica\Module\BaseApi;
*/
class Unfavourite extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();

View file

@ -32,7 +32,7 @@ use Friendica\Module\BaseApi;
*/
class Unmute extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();

View file

@ -32,7 +32,7 @@ use Friendica\Module\BaseApi;
*/
class Unpin extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();

View file

@ -35,7 +35,7 @@ use Friendica\Module\BaseApi;
*/
class Unreblog extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
$uid = self::getCurrentUserID();

View file

@ -39,7 +39,7 @@ class Suggestions extends BaseApi
self::checkAllowedScope(self::SCOPE_READ);
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'limit' => 40, // Maximum number of results to return. Defaults to 40.
], $request);

View file

@ -40,7 +40,7 @@ class Direct extends BaseApi
self::checkAllowedScope(self::SCOPE_READ);
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'max_id' => 0, // Return results older than id
'since_id' => 0, // Return results newer than id
'min_id' => 0, // Return results immediately newer than id

View file

@ -41,7 +41,7 @@ class Home extends BaseApi
self::checkAllowedScope(self::SCOPE_READ);
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'max_id' => 0, // Return results older than id
'since_id' => 0, // Return results newer than id
'min_id' => 0, // Return results immediately newer than id

View file

@ -45,7 +45,7 @@ class ListTimeline extends BaseApi
DI::mstdnError()->UnprocessableEntity();
}
$request = self::getRequest([
$request = $this->getRequest([
'max_id' => 0, // Return results older than id
'since_id' => 0, // Return results newer than id
'min_id' => 0, // Return results immediately newer than id

View file

@ -43,7 +43,7 @@ class PublicTimeline extends BaseApi
{
$uid = self::getCurrentUserID();
$request = self::getRequest([
$request = $this->getRequest([
'local' => false, // Show only local statuses? Defaults to false.
'remote' => false, // Show only remote statuses? Defaults to false.
'only_media' => false, // Show only statuses with media attached? Defaults to false.

View file

@ -53,7 +53,7 @@ class Tag extends BaseApi
* There seem to be the parameters "any", "all", and "none".
*/
$request = self::getRequest([
$request = $this->getRequest([
'local' => false, // If true, return only local statuses. Defaults to false.
'remote' => false, // Show only remote statuses? Defaults to false.
'only_media' => false, // If true, return only statuses with media attachments. Defaults to false.

View file

@ -36,7 +36,7 @@ class Trends extends BaseApi
*/
protected function rawContent(array $request = [])
{
$request = self::getRequest([
$request = $this->getRequest([
'limit' => 20, // Maximum number of results to return. Defaults to 10.
], $request);

View file

@ -32,33 +32,33 @@ class Unimplemented extends BaseApi
/**
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
protected function delete()
protected function delete(array $request = [])
{
$this->response->unsupported(Router::DELETE);
$this->response->unsupported(Router::DELETE, $request);
}
/**
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
protected function patch()
protected function patch(array $request = [])
{
$this->response->unsupported(Router::PATCH);
$this->response->unsupported(Router::PATCH, $request);
}
/**
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
$this->response->unsupported(Router::POST);
$this->response->unsupported(Router::POST, $request);
}
/**
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
public function put()
public function put(array $request = [])
{
$this->response->unsupported(Router::PUT);
$this->response->unsupported(Router::PUT, $request);
}
/**
@ -66,6 +66,6 @@ class Unimplemented extends BaseApi
*/
protected function rawContent(array $request = [])
{
$this->response->unsupported(Router::GET);
$this->response->unsupported(Router::GET, $request);
}
}

View file

@ -64,6 +64,6 @@ class UpdateProfile extends BaseApi
// "uid" is only needed for some internal stuff, so remove it from here
unset($user_info['uid']);
DI::apiResponse()->exit('user', ['user' => $user_info], $this->parameters['extension'] ?? null);
$this->response->exit('user', ['user' => $user_info], $this->parameters['extension'] ?? null);
}
}

View file

@ -47,6 +47,6 @@ class VerifyCredentials extends BaseApi
// "uid" is only needed for some internal stuff, so remove it from here
unset($user_info['uid']);
DI::apiResponse()->exit('user', ['user' => $user_info], $this->parameters['extension'] ?? null);
$this->response->exit('user', ['user' => $user_info], $this->parameters['extension'] ?? null);
}
}

View file

@ -72,6 +72,6 @@ class Favorites extends BaseApi
}
DBA::close($statuses);
DI::apiResponse()->exit('statuses', ['status' => $ret], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
$this->response->exit('statuses', ['status' => $ret], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
}
}

View file

@ -46,6 +46,6 @@ class Create extends BaseApi
$status_info = DI::twitterStatus()->createFromItemId($id, $uid)->toArray();
DI::apiResponse()->exit('status', ['status' => $status_info], $this->parameters['extension'] ?? null);
$this->response->exit('status', ['status' => $status_info], $this->parameters['extension'] ?? null);
}
}

View file

@ -46,6 +46,6 @@ class Destroy extends BaseApi
$status_info = DI::twitterStatus()->createFromItemId($id, $uid)->toArray();
DI::apiResponse()->exit('status', ['status' => $status_info], $this->parameters['extension'] ?? null);
$this->response->exit('status', ['status' => $status_info], $this->parameters['extension'] ?? null);
}
}

View file

@ -81,6 +81,6 @@ class Destroy extends ContactEndpoint
throw new HTTPException\InternalServerErrorException('Unable to unfollow this contact, please contact your administrator');
}
DI::apiResponse()->exit('friendships', ['user' => $user], $this->parameters['extension'] ?? null);
$this->response->exit('friendships', ['user' => $user], $this->parameters['extension'] ?? null);
}
}

View file

@ -83,6 +83,6 @@ class Statuses extends BaseApi
}
DBA::close($statuses);
DI::apiResponse()->exit('statuses', ['status' => $items], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
$this->response->exit('statuses', ['status' => $items], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
}
}

View file

@ -65,6 +65,6 @@ class Upload extends BaseApi
Logger::info('Media uploaded', ['return' => $returndata]);
DI::apiResponse()->exit('media', ['media' => $returndata], $this->parameters['extension'] ?? null);
$this->response->exit('media', ['media' => $returndata], $this->parameters['extension'] ?? null);
}
}

View file

@ -77,7 +77,8 @@ class Tweets extends BaseApi
DBA::close($tags);
if (empty($uriids)) {
DI::apiResponse()->exit('statuses', $data, $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
$this->response->exit('statuses', $data, $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
return;
}
$condition = ['uri-id' => $uriids];
@ -122,6 +123,6 @@ class Tweets extends BaseApi
}
DBA::close($statuses);
DI::apiResponse()->exit('statuses', ['status' => $ret], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
$this->response->exit('statuses', ['status' => $ret], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
}
}

View file

@ -53,6 +53,6 @@ class Destroy extends BaseApi
Item::deleteForUser(['id' => $id], $uid);
DI::apiResponse()->exit('status', ['status' => $ret], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
$this->response->exit('status', ['status' => $ret], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
}
}

View file

@ -88,6 +88,6 @@ class HomeTimeline extends BaseApi
}
}
DI::apiResponse()->exit('statuses', ['status' => $ret], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
$this->response->exit('statuses', ['status' => $ret], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
}
}

View file

@ -80,6 +80,6 @@ class Mentions extends BaseApi
}
DBA::close($statuses);
DI::apiResponse()->exit('statuses', ['status' => $ret], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
$this->response->exit('statuses', ['status' => $ret], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
}
}

View file

@ -66,6 +66,6 @@ class NetworkPublicTimeline extends BaseApi
}
DBA::close($statuses);
DI::apiResponse()->exit('statuses', ['status' => $ret], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
$this->response->exit('statuses', ['status' => $ret], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
}
}

View file

@ -86,6 +86,6 @@ class PublicTimeline extends BaseApi
}
DBA::close($statuses);
DI::apiResponse()->exit('statuses', ['status' => $ret], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
$this->response->exit('statuses', ['status' => $ret], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
}
}

View file

@ -89,10 +89,10 @@ class Show extends BaseApi
if ($conversation) {
$data = ['status' => $ret];
DI::apiResponse()->exit('statuses', $data, $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
$this->response->exit('statuses', $data, $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
} else {
$data = ['status' => $ret[0]];
DI::apiResponse()->exit('status', ['status' => $ret], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
$this->response->exit('status', ['status' => $data], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
}
}
}

View file

@ -82,6 +82,6 @@ class UserTimeline extends BaseApi
}
DBA::close($statuses);
DI::apiResponse()->exit('user', ['status' => $ret], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
$this->response->exit('user', ['status' => $ret], $this->parameters['extension'] ?? null, Contact::getPublicIdByUserId($uid));
}
}

View file

@ -51,6 +51,6 @@ class Lookup extends BaseApi
throw new NotFoundException();
}
DI::apiResponse()->exit('users', ['user' => $users], $this->parameters['extension'] ?? null);
$this->response->exit('users', ['user' => $users], $this->parameters['extension'] ?? null);
}
}

View file

@ -69,6 +69,6 @@ class Search extends BaseApi
throw new BadRequestException('No search term specified.');
}
DI::apiResponse()->exit('users', ['user' => $userlist], $this->parameters['extension'] ?? null);
$this->response->exit('users', ['user' => $userlist], $this->parameters['extension'] ?? null);
}
}

View file

@ -48,6 +48,6 @@ class Show extends BaseApi
// "uid" is only needed for some internal stuff, so remove it from here
unset($user_info['uid']);
DI::apiResponse()->exit('user', ['user' => $user_info], $this->parameters['extension'] ?? null);
$this->response->exit('user', ['user' => $user_info], $this->parameters['extension'] ?? null);
}
}

View file

@ -22,6 +22,7 @@
namespace Friendica\Module;
use Friendica\App;
use Friendica\App\Router;
use Friendica\BaseModule;
use Friendica\Core\L10n;
use Friendica\Core\Logger;
@ -35,8 +36,8 @@ use Friendica\Network\HTTPException;
use Friendica\Security\BasicAuth;
use Friendica\Security\OAuth;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\HTTPInputData;
use Friendica\Util\Profiler;
use Psr\Http\Message\ResponseInterface;
use Psr\Log\LoggerInterface;
class BaseApi extends BaseModule
@ -71,40 +72,29 @@ class BaseApi extends BaseModule
$this->app = $app;
}
protected function delete()
/**
* Additionally checks, if the caller is permitted to do this action
*
* {@inheritDoc}
*
* @throws HTTPException\ForbiddenException
*/
public function run(array $request = []): ResponseInterface
{
self::checkAllowedScope(self::SCOPE_WRITE);
switch ($this->server['REQUEST_METHOD'] ?? Router::GET) {
case Router::DELETE:
case Router::PATCH:
case Router::POST:
case Router::PUT:
self::checkAllowedScope(self::SCOPE_WRITE);
if (!$this->app->isLoggedIn()) {
throw new HTTPException\ForbiddenException($this->t('Permission denied.'));
if (!$this->app->isLoggedIn()) {
throw new HTTPException\ForbiddenException($this->t('Permission denied.'));
}
break;
}
}
protected function patch()
{
self::checkAllowedScope(self::SCOPE_WRITE);
if (!$this->app->isLoggedIn()) {
throw new HTTPException\ForbiddenException($this->t('Permission denied.'));
}
}
protected function post(array $request = [], array $post = [])
{
self::checkAllowedScope(self::SCOPE_WRITE);
if (!$this->app->isLoggedIn()) {
throw new HTTPException\ForbiddenException($this->t('Permission denied.'));
}
}
public function put()
{
self::checkAllowedScope(self::SCOPE_WRITE);
if (!$this->app->isLoggedIn()) {
throw new HTTPException\ForbiddenException($this->t('Permission denied.'));
}
return parent::run($request);
}
/**
@ -112,49 +102,18 @@ class BaseApi extends BaseModule
*
* @param array $defaults Associative array of expected request keys and their default typed value. A null
* value will remove the request key from the resulting value array.
* @param array|null $request Custom REQUEST array, superglobal instead
* @param array $request Custom REQUEST array, superglobal instead
* @return array request data
* @throws \Exception
*/
public static function getRequest(array $defaults, array $request = null): array
public function getRequest(array $defaults, array $request): array
{
$httpinput = HTTPInputData::process();
$input = array_merge($httpinput['variables'], $httpinput['files'], $request ?? $_REQUEST);
self::$request = $input;
self::$request = $request;
self::$boundaries = [];
unset(self::$request['pagename']);
$request = [];
foreach ($defaults as $parameter => $defaultvalue) {
if (is_string($defaultvalue)) {
$request[$parameter] = $input[$parameter] ?? $defaultvalue;
} elseif (is_int($defaultvalue)) {
$request[$parameter] = (int)($input[$parameter] ?? $defaultvalue);
} elseif (is_float($defaultvalue)) {
$request[$parameter] = (float)($input[$parameter] ?? $defaultvalue);
} elseif (is_array($defaultvalue)) {
$request[$parameter] = $input[$parameter] ?? [];
} elseif (is_bool($defaultvalue)) {
$request[$parameter] = in_array(strtolower($input[$parameter] ?? ''), ['true', '1']);
} else {
Logger::notice('Unhandled default value type', ['parameter' => $parameter, 'type' => gettype($defaultvalue)]);
}
}
foreach ($input ?? [] as $parameter => $value) {
if ($parameter == 'pagename') {
continue;
}
if (!in_array($parameter, array_keys($defaults))) {
Logger::notice('Unhandled request field', ['parameter' => $parameter, 'value' => $value, 'command' => DI::args()->getCommand()]);
}
}
Logger::debug('Got request parameters', ['request' => $request, 'command' => DI::args()->getCommand()]);
return $request;
return $this->checkDefaults($defaults, $request);
}
/**

View file

@ -91,7 +91,7 @@ class Contact extends BaseModule
DI::baseUrl()->redirect($redirectUrl);
}
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!local_user()) {
return;

View file

@ -61,7 +61,7 @@ class Advanced extends BaseModule
}
}
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
$cid = $this->parameters['id'];

View file

@ -18,7 +18,7 @@ use Friendica\Util\XML;
class Poke extends BaseModule
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!local_user() || empty($this->parameters['id'])) {
return self::postReturn(false);

View file

@ -71,7 +71,7 @@ class Profile extends BaseModule
$this->config = $config;
}
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!local_user()) {
return;

View file

@ -74,7 +74,7 @@ class Revoke extends BaseModule
}
}
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!local_user()) {
throw new HTTPException\UnauthorizedException();

View file

@ -38,7 +38,7 @@ use Friendica\Network\HTTPException;
*/
class Notify extends BaseModule
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
$postdata = Network::postdata();

View file

@ -31,7 +31,7 @@ class Localtime extends BaseModule
{
static $mod_localtime = '';
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
$time = ($_REQUEST['time'] ?? '') ?: 'now';

View file

@ -37,7 +37,7 @@ use Friendica\Util\Proxy;
*/
class Delegation extends BaseModule
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!local_user()) {
return;

View file

@ -49,7 +49,7 @@ class Receive extends BaseModule
$this->config = $config;
}
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
$enabled = $this->config->get('system', 'diaspora_enabled', false);
if (!$enabled) {

View file

@ -10,9 +10,9 @@ use Friendica\Model\Contact;
*/
class FollowConfirm extends BaseModule
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
parent::post($post);
parent::post($request);
$uid = local_user();
if (!$uid) {
notice(DI::l10n()->t('Permission denied.'));

View file

@ -61,7 +61,7 @@ class FriendSuggest extends BaseModule
$this->friendSuggestFac = $friendSuggestFac;
}
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
$cid = intval($this->parameters['contact']);

View file

@ -32,7 +32,7 @@ require_once 'boot.php';
class Group extends BaseModule
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (DI::mode()->isAjax()) {
$this->ajaxPost();
@ -47,7 +47,7 @@ class Group extends BaseModule
if ((DI::args()->getArgc() == 2) && (DI::args()->getArgv()[1] === 'new')) {
BaseModule::checkFormSecurityTokenRedirectOnError('/group/new', 'group_edit');
$name = trim($_POST['groupname']);
$name = trim($request['groupname']);
$r = Model\Group::create(local_user(), $name);
if ($r) {
$r = Model\Group::getIdByName(local_user(), $name);

View file

@ -33,7 +33,7 @@ class PageNotFound extends BaseModule
throw new HTTPException\NotFoundException(DI::l10n()->t('Page not found.'));
}
public function run(array $post = [], array $request = []): ResponseInterface
public function run(array $request = []): ResponseInterface
{
/* The URL provided does not resolve to a valid module.
*
@ -61,6 +61,6 @@ class PageNotFound extends BaseModule
'query' => $this->server['QUERY_STRING']
]);
return parent::run($post, $request); // TODO: Change the autogenerated stub
return parent::run($request); // TODO: Change the autogenerated stub
}
}

View file

@ -104,7 +104,7 @@ class Install extends BaseModule
$this->currentWizardStep = ($_POST['pass'] ?? '') ?: self::SYSTEM_CHECK;
}
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
$configCache = $this->app->getConfigCache();

View file

@ -35,7 +35,7 @@ use Friendica\Util\Strings;
*/
class Invite extends BaseModule
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!local_user()) {
throw new HTTPException\ForbiddenException(DI::l10n()->t('Permission denied.'));

View file

@ -40,7 +40,7 @@ use Friendica\Util\Temporal;
class Compose extends BaseModule
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!empty($_REQUEST['body'])) {
$_REQUEST['return'] = 'network';

View file

@ -42,7 +42,7 @@ class Notification extends BaseModule
* @throws \ImagickException
* @throws \Exception
*/
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!local_user()) {
throw new HTTPException\UnauthorizedException(DI::l10n()->t('Permission denied.'));

View file

@ -30,7 +30,7 @@ use Friendica\Module\BaseApi;
*/
class Acknowledge extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
DI::session()->set('oauth_acknowledge', true);
DI::app()->redirect(DI::session()->get('return_path'));

View file

@ -39,7 +39,7 @@ class Authorize extends BaseApi
*/
protected function rawContent(array $request = [])
{
$request = self::getRequest([
$request = $this->getRequest([
'force_login' => '', // Forces the user to re-login, which is necessary for authorizing with multiple accounts from the same instance.
'response_type' => '', // Should be set equal to "code".
'client_id' => '', // Client ID, obtained during app registration.

View file

@ -32,9 +32,9 @@ use Friendica\Module\BaseApi;
*/
class Revoke extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
$request = self::getRequest([
$request = $this->getRequest([
'client_id' => '', // Client ID, obtained during app registration
'client_secret' => '', // Client secret, obtained during app registration
'token' => '', // The previously obtained token, to be invalidated

View file

@ -34,9 +34,9 @@ use Friendica\Security\OAuth;
*/
class Token extends BaseApi
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
$request = self::getRequest([
$request = $this->getRequest([
'client_id' => '', // Client ID, obtained during app registration
'client_secret' => '', // Client secret, obtained during app registration
'redirect_uri' => '', // Set a URI to redirect the user to. If this parameter is set to "urn:ietf:wg:oauth:2.0:oob" then the token will be shown instead. Must match one of the redirect URIs declared during app registration.

View file

@ -33,7 +33,7 @@ use Friendica\Util\DateTimeFormat;
class Schedule extends BaseProfile
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!local_user()) {
throw new HTTPException\ForbiddenException(DI::l10n()->t('Permission denied.'));

View file

@ -193,7 +193,7 @@ class Register extends BaseModule
* Extend this method if the module is supposed to process POST requests.
* Doesn't display any content
*/
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
BaseModule::checkFormSecurityTokenRedirectOnError('/register', 'register');

View file

@ -61,7 +61,7 @@ class RemoteFollow extends BaseModule
$this->page = $page;
}
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!empty($_POST['cancel']) || empty($_POST['dfrn_url'])) {
$this->baseUrl->redirect();

View file

@ -46,7 +46,7 @@ class Login extends BaseModule
return self::form(Session::get('return_path'), intval(DI::config()->get('config', 'register_policy')) !== \Friendica\Module\Register::CLOSED);
}
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
$return_path = Session::get('return_path');
Session::clear();

View file

@ -56,7 +56,7 @@ class Recovery extends BaseModule
$this->session = $session;
}
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!local_user()) {
return;

View file

@ -38,7 +38,7 @@ class Verify extends BaseModule
{
private static $errors = [];
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!local_user()) {
return;

View file

@ -36,7 +36,7 @@ use Friendica\Util\Strings;
*/
class Delegation extends BaseSettings
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!DI::app()->isLoggedIn()) {
throw new HTTPException\ForbiddenException(DI::l10n()->t('Permission denied.'));

View file

@ -36,7 +36,7 @@ use Friendica\Network\HTTPException;
*/
class Display extends BaseSettings
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!DI::app()->isLoggedIn()) {
throw new HTTPException\ForbiddenException(DI::l10n()->t('Permission denied.'));

View file

@ -41,7 +41,7 @@ use Friendica\Util\Temporal;
class Index extends BaseSettings
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!local_user()) {
return;

View file

@ -33,7 +33,7 @@ use Friendica\Network\HTTPException;
class Crop extends BaseSettings
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!Session::isAuthenticated()) {
return;

View file

@ -34,7 +34,7 @@ use Friendica\Util\Strings;
class Index extends BaseSettings
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!Session::isAuthenticated()) {
return;

View file

@ -66,7 +66,7 @@ class AppSpecific extends BaseSettings
}
}
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!local_user()) {
return;

View file

@ -33,7 +33,7 @@ use PragmaRX\Google2FA\Google2FA;
class Index extends BaseSettings
{
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!local_user()) {
return;

View file

@ -64,7 +64,7 @@ class Recovery extends BaseSettings
}
}
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!local_user()) {
return;

View file

@ -48,7 +48,7 @@ class Trusted extends BaseSettings
}
}
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!local_user()) {
return;

View file

@ -70,7 +70,7 @@ class Verify extends BaseSettings
}
}
protected function post(array $request = [], array $post = [])
protected function post(array $request = [])
{
if (!local_user()) {
return;

View file

@ -27,9 +27,22 @@ namespace Friendica\Util;
*/
class HTTPInputData
{
public static function process()
/** @var array The $_SERVER variable */
protected $server;
public function __construct(array $server)
{
$content_parts = explode(';', static::getContentType());
$this->server = $server;
}
/**
* Process the PHP input stream and creates an array with its content
*
* @return array|array[]
*/
public function process(): array
{
$content_parts = explode(';', $this->server['CONTENT_TYPE'] ?? 'application/x-www-form-urlencoded');
$boundary = '';
$encoding = '';
@ -54,7 +67,7 @@ class HTTPInputData
}
if ($content_type == 'multipart/form-data') {
return self::fetchFromMultipart($boundary);
return $this->fetchFromMultipart($boundary);
}
// can be handled by built in PHP functionality
@ -69,7 +82,7 @@ class HTTPInputData
return ['variables' => $variables, 'files' => []];
}
private static function fetchFromMultipart(string $boundary)
private function fetchFromMultipart(string $boundary): array
{
$result = ['variables' => [], 'files' => []];
@ -94,7 +107,7 @@ class HTTPInputData
continue;
}
$result = self::parseRawHeader($stream, $raw_headers, $boundary, $result);
$result = $this->parseRawHeader($stream, $raw_headers, $boundary, $result);
$raw_headers = '';
}
@ -104,7 +117,7 @@ class HTTPInputData
return $result;
}
private static function parseRawHeader($stream, string $raw_headers, string $boundary, array $result)
private function parseRawHeader($stream, string $raw_headers, string $boundary, array $result)
{
$variables = $result['variables'];
$files = $result['files'];
@ -115,7 +128,7 @@ class HTTPInputData
if (strpos($header, ':') === false) {
continue;
}
list($name, $value) = explode(':', $header, 2);
[$name, $value] = explode(':', $header, 2);
$headers[strtolower($name)] = ltrim($value, ' ');
}
@ -135,13 +148,13 @@ class HTTPInputData
$files[$name] = static::fetchFileData($stream, $boundary, $headers, $filename);
return ['variables' => $variables, 'files' => $files];
} else {
$variables = self::fetchVariables($stream, $boundary, $headers, $name, $variables);
$variables = $this->fetchVariables($stream, $boundary, $headers, $name, $variables);
}
return ['variables' => $variables, 'files' => $files];
}
protected static function fetchFileData($stream, string $boundary, array $headers, string $filename)
protected function fetchFileData($stream, string $boundary, array $headers, string $filename)
{
$error = UPLOAD_ERR_OK;
@ -186,7 +199,7 @@ class HTTPInputData
];
}
private static function fetchVariables($stream, string $boundary, array $headers, string $name, array $variables)
private function fetchVariables($stream, string $boundary, array $headers, string $name, array $variables)
{
$fullValue = '';
$lastLine = null;
@ -229,10 +242,10 @@ class HTTPInputData
$tmp = [];
parse_str($fullValue, $tmp);
return self::expandVariables(explode('[', $name), $variables, $tmp);
return $this->expandVariables(explode('[', $name), $variables, $tmp);
}
private static function expandVariables(array $names, $variables, array $values)
private function expandVariables(array $names, $variables, array $values)
{
if (!is_array($variables)) {
return $values;
@ -252,7 +265,7 @@ class HTTPInputData
if ($name === '') {
$variables[] = reset($values);
} elseif (isset($variables[$name]) && isset($values[$name])) {
$variables[$name] = self::expandVariables($names, $variables[$name], $values[$name]);
$variables[$name] = $this->expandVariables($names, $variables[$name], $values[$name]);
} elseif (isset($values[$name])) {
$variables[$name] = $values[$name];
}
@ -266,7 +279,7 @@ class HTTPInputData
*
* @return false|resource
*/
protected static function getPhpInputStream()
protected function getPhpInputStream()
{
return fopen('php://input', 'rb');
}
@ -277,19 +290,8 @@ class HTTPInputData
*
* @return false|string
*/
protected static function getPhpInputContent()
protected function getPhpInputContent()
{
return file_get_contents('php://input');
}
/**
* Returns the content type string of the current call
* Mainly used for test doubling
*
* @return false|string
*/
protected static function getContentType()
{
return $_SERVER['CONTENT_TYPE'] ?? 'application/x-www-form-urlencoded';
}
}

View file

@ -30,20 +30,18 @@ use Friendica\Util\HTTPInputData;
class HTTPInputDataDouble extends HTTPInputData
{
/** @var false|resource */
protected static $injectedStream = false;
protected $injectedStream = false;
/** @var false|string */
protected static $injectedContent = false;
/** @var false|string */
protected static $injectedContentType = false;
protected $injectedContent = false;
/**
* injects the PHP input stream for a test
*
* @param false|resource $stream
*/
public static function setPhpInputStream($stream)
public function setPhpInputStream($stream)
{
self::$injectedStream = $stream;
$this->injectedStream = $stream;
}
/**
@ -51,9 +49,9 @@ class HTTPInputDataDouble extends HTTPInputData
*
* @param false|string $content
*/
public static function setPhpInputContent($content)
public function setPhpInputContent($content)
{
self::$injectedContent = $content;
$this->injectedContent = $content;
}
/**
@ -61,30 +59,24 @@ class HTTPInputDataDouble extends HTTPInputData
*
* @param false|string $contentType
*/
public static function setPhpInputContentType($contentType)
public function setPhpInputContentType($contentType)
{
self::$injectedContentType = $contentType;
$this->injectedContentType = $contentType;
}
/** {@inheritDoc} */
protected static function getPhpInputStream()
protected function getPhpInputStream()
{
return static::$injectedStream;
return $this->injectedStream;
}
/** {@inheritDoc} */
protected static function getPhpInputContent()
protected function getPhpInputContent()
{
return static::$injectedContent;
return $this->injectedContent;
}
/** {@inheritDoc} */
protected static function getContentType()
{
return static::$injectedContentType;
}
protected static function fetchFileData($stream, string $boundary, array $headers, string $filename)
protected function fetchFileData($stream, string $boundary, array $headers, string $filename)
{
$data = parent::fetchFileData($stream, $boundary, $headers, $filename);
if (!empty($data['tmp_name'])) {

View file

@ -51,7 +51,7 @@ class DeleteTest extends ApiTest
$this->loadFixture(__DIR__ . '/../../../../../datasets/photo/photo.fixture.php', DI::dba());
$delete = new Delete(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), ['REQUEST_METHOD' => Router::POST]);
$response = $delete->run([], ['photo_id' => '709057080661a283a6aa598501504178']);
$response = $delete->run(['photo_id' => '709057080661a283a6aa598501504178']);
$responseText = (string)$response->getBody();
@ -68,7 +68,7 @@ class DeleteTest extends ApiTest
$this->loadFixture(__DIR__ . '/../../../../../datasets/photo/photo.fixture.php', DI::dba());
$delete = new Delete(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), ['REQUEST_METHOD' => Router::POST]);
$response = $delete->run([], ['photo_id' => '709057080661a283a6aa598501504178']);
$response = $delete->run(['photo_id' => '709057080661a283a6aa598501504178']);
$responseText = (string)$response->getBody();

View file

@ -47,7 +47,7 @@ class DeleteTest extends ApiTest
$this->loadFixture(__DIR__ . '/../../../../../datasets/photo/photo.fixture.php', DI::dba());
$delete = new Delete(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), ['REQUEST_METHOD' => Router::POST]);
$response = $delete->run([], ['album' => 'test_album']);
$response = $delete->run(['album' => 'test_album']);
$responseText = (string)$response->getBody();

View file

@ -56,7 +56,7 @@ class UpdateTest extends ApiTest
{
$this->loadFixture(__DIR__ . '/../../../../../datasets/photo/photo.fixture.php', DI::dba());
$response = (new Update(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), ['REQUEST_METHOD' => Router::POST]))->run([], ['album' => 'test_album', 'album_new' => 'test_album_2']);
$response = (new Update(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), ['REQUEST_METHOD' => Router::POST]))->run(['album' => 'test_album', 'album_new' => 'test_album_2']);
$responseBody = (string)$response->getBody();

View file

@ -139,14 +139,15 @@ class HTTPInputDataTest extends MockedTest
*/
public function testHttpInput(string $contentType, string $input, array $expected)
{
HTTPInputDataDouble::setPhpInputContentType($contentType);
HTTPInputDataDouble::setPhpInputContent($input);
$httpInput = new HTTPInputDataDouble(['CONTENT_TYPE' => $contentType]);
$httpInput->setPhpInputContent($input);
$stream = fopen('php://memory', 'r+');
fwrite($stream, $input);
rewind($stream);
HTTPInputDataDouble::setPhpInputStream($stream);
$output = HTTPInputDataDouble::process();
$httpInput->setPhpInputStream($stream);
$output = $httpInput->process();
$this->assertEqualsCanonicalizing($expected, $output);
}
}