diff --git a/src/App/Router.php b/src/App/Router.php index e90cb3ace..78d8ab629 100644 --- a/src/App/Router.php +++ b/src/App/Router.php @@ -44,12 +44,18 @@ use Friendica\Network\HTTPException; */ class Router { - const POST = 'POST'; - const GET = 'GET'; + const DELETE = 'DELETE'; + const GET = 'GET'; + const PATCH = 'PATCH'; + const POST = 'POST'; + const PUT = 'PUT'; const ALLOWED_METHODS = [ - self::POST, + self::DELETE, self::GET, + self::PATCH, + self::POST, + self::PUT, ]; /** @var RouteCollector */ diff --git a/src/Module/Api/Mastodon/Unimplemented.php b/src/Module/Api/Mastodon/Unimplemented.php new file mode 100644 index 000000000..c5adbe5d9 --- /dev/null +++ b/src/Module/Api/Mastodon/Unimplemented.php @@ -0,0 +1,47 @@ +. + * + */ + +namespace Friendica\Module\Api\Mastodon; + +use Friendica\Core\Logger; +use Friendica\Core\System; +use Friendica\DI; +use Friendica\Module\BaseApi; + +/** + * Dummy class for all currently unimplemented endpoints + */ +class Unimplemented extends BaseApi +{ + /** + * @param array $parameters + * @throws \Friendica\Network\HTTPException\InternalServerErrorException + */ + public static function rawContent(array $parameters = []) + { + $path = DI::args()->getQueryString(); + Logger::info('Unimplemented API call', ['path' => $path]); + $error = DI::l10n()->t('API endpoint "%s" is not implemented', $path); + $error_description = DI::l10n()->t('The API endpoint is currently not implemented but might be in the future.');; + $errorobj = new \Friendica\Object\Api\Mastodon\Error($error, $error_description); + System::jsonError(501, $errorobj->toArray()); + } +} diff --git a/static/routes.config.php b/static/routes.config.php index f0627b612..4ad122fbf 100644 --- a/static/routes.config.php +++ b/static/routes.config.php @@ -56,17 +56,100 @@ return [ '/api' => [ '/v1' => [ + '/accounts' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], '/accounts/{id:\d+}' => [Module\Api\Mastodon\Accounts::class, [R::GET ]], '/accounts/{id:\d+}/statuses' => [Module\Api\Mastodon\Accounts\Statuses::class, [R::GET ]], + '/accounts/{id:\d+}/followers' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/accounts/{id:\d+}/following' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/accounts/{id:\d+}/lists' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/accounts/{id:\d+}/identity_proofs' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/accounts/{id:\d+}/follow' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/accounts/{id:\d+}/unfollow' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/accounts/{id:\d+}/block' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/accounts/{id:\d+}/unblock' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/accounts/{id:\d+}/mute' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/accounts/{id:\d+}/unmute' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/accounts/{id:\d+}/pin' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/accounts/{id:\d+}/unpin' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/accounts/{id:\d+}/note' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/accounts/relationships' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/accounts/search' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/accounts/verify_credentials' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/accounts/update_credentials' => [Module\Api\Mastodon\Unimplemented::class, [R::PATCH ]], + '/admin/accounts' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/admin/accounts/{id:\d+}' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/admin/accounts/{id:\d+}/{action}' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/admin/reports' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/admin/reports/{id:\d+}' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/admin/reports/{id:\d+}/{action}' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/announcements' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/announcements/{id:\d+}/dismiss' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/announcements/{id:\d+}/reactions/{name}' => [Module\Api\Mastodon\Unimplemented::class, [R::PUT, R::DELETE]], + '/apps' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/apps/verify_credentials' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/blocks' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/bookmarks' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/conversations' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/conversations/{id:\d+}' => [Module\Api\Mastodon\Unimplemented::class, [R::DELETE ]], + '/conversations/{id:\d+}/read' => [Module\Api\Mastodon\Unimplemented::class, [R::POST ]], '/custom_emojis' => [Module\Api\Mastodon\CustomEmojis::class, [R::GET ]], + '/domain_blocks' => [Module\Api\Mastodon\Unimplemented::class, [R::GET, R::POST, R::DELETE]], '/directory' => [Module\Api\Mastodon\Directory::class, [R::GET ]], + '/endorsements' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/favourites' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/featured_tags' => [Module\Api\Mastodon\Unimplemented::class, [R::GET, R::POST]], + '/featured_tags/{id:\d+}' => [Module\Api\Mastodon\Unimplemented::class, [R::DELETE ]], + '/featured_tags/suggestions' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/filters' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/filters/{id:\d+}' => [Module\Api\Mastodon\Unimplemented::class, [R::GET, R::POST, R::PUT, R::DELETE]], '/follow_requests' => [Module\Api\Mastodon\FollowRequests::class, [R::GET ]], '/follow_requests/{id:\d+}/{action}' => [Module\Api\Mastodon\FollowRequests::class, [ R::POST]], '/instance' => [Module\Api\Mastodon\Instance::class, [R::GET ]], + '/instance/activity' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], '/instance/peers' => [Module\Api\Mastodon\Instance\Peers::class, [R::GET ]], + '/lists' => [Module\Api\Mastodon\Unimplemented::class, [R::GET, R::POST]], + '/lists/{id:\d+}' => [Module\Api\Mastodon\Unimplemented::class, [R::GET, R::PUT, R::DELETE]], + '/lists/{id:\d+}/accounts' => [Module\Api\Mastodon\Unimplemented::class, [R::GET, R::POST, R::DELETE]], + '/markers' => [Module\Api\Mastodon\Unimplemented::class, [R::GET, R::POST]], + '/media' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/media/{id:\d+}' => [Module\Api\Mastodon\Unimplemented::class, [R::GET, R::PUT]], + '/mutes' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/notifications' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/notifications/{id:\d+}' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/notifications/clear' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/notifications/{id:\d+}/dismiss' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/polls/{id:\d+}' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/polls/{id:\d+}/votes' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/preferences' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/reports' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/scheduled_statuses' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/scheduled_statuses/{id:\d+}' => [Module\Api\Mastodon\Unimplemented::class, [R::GET, R::PUT, R::DELETE]], + '/statuses' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/statuses/{id:\d+}' => [Module\Api\Mastodon\Unimplemented::class, [R::GET, R::DELETE]], + '/statuses/{id:\d+}/context' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/statuses/{id:\d+}/reblogged_by' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/statuses/{id:\d+}/favourited_by' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/statuses/{id:\d+}/favourite' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/statuses/{id:\d+}/unfavourite' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/statuses/{id:\d+}/reblog' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/statuses/{id:\d+}/unreblog' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/statuses/{id:\d+}/bookmark' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/statuses/{id:\d+}/unbookmark' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/statuses/{id:\d+}/mute' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/statuses/{id:\d+}/unmute' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/statuses/{id:\d+}/pin' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/statuses/{id:\d+}/unpin' => [Module\Api\Mastodon\Unimplemented::class, [ R::POST]], + '/suggestions' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/suggestions/{id:\d+}' => [Module\Api\Mastodon\Unimplemented::class, [R::DELETE ]], + '/timelines/home' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + '/timelines/list/{id:\d+}' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], '/timelines/public' => [Module\Api\Mastodon\Timelines\PublicTimeline::class, [R::GET ]], + '/timelines/tag/{hashtag}' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], '/trends' => [Module\Api\Mastodon\Trends::class, [R::GET ]], ], + '/v2' => [ + '/search' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], + ], '/friendica' => [ '/profile/show' => [Module\Api\Friendica\Profile\Show::class , [R::GET ]], '/events' => [Module\Api\Friendica\Events\Index::class , [R::GET ]], @@ -75,6 +158,7 @@ return [ '/followers/list' => [Module\Api\Twitter\FollowersList::class , [R::GET ]], '/friends/ids' => [Module\Api\Twitter\FriendsIds::class , [R::GET ]], '/friends/list' => [Module\Api\Twitter\FriendsList::class , [R::GET ]], + '/oembed' => [Module\Api\Mastodon\Unimplemented::class, [R::GET ]], ], '/admin' => [ @@ -243,6 +327,9 @@ return [ '/mark/all' => [Module\Notifications\Notification::class, [R::GET]], '/{id:\d+}' => [Module\Notifications\Notification::class, [R::GET, R::POST]], ], + '/oauth/authorize' => [Module\Api\Mastodon\Unimplemented::class, [R::GET]], + '/oauth/revoke' => [Module\Api\Mastodon\Unimplemented::class, [R::POST]], + '/oauth/token' => [Module\Api\Mastodon\Unimplemented::class, [R::POST]], '/objects/{guid}[/{activity}]' => [Module\Objects::class, [R::GET]], '/oembed' => [ @@ -267,6 +354,8 @@ return [ '/pretheme' => [Module\ThemeDetails::class, [R::GET]], '/probe' => [Module\Debug\Probe::class, [R::GET]], + '/proofs' => [Module\Api\Mastodon\Unimplemented::class, [R::GET]], + '/profile/{nickname}' => $profileRoutes, '/u/{nickname}' => $profileRoutes, '/~{nickname}' => $profileRoutes,