Merge pull request #10527 from annando/api
API: Support for deprecated API endpoints and OAuth removal
This commit is contained in:
commit
1e6031fc23
13 changed files with 75 additions and 58 deletions
|
@ -2,6 +2,7 @@ Version 2021.09 (unreleased)
|
||||||
Friendica Core
|
Friendica Core
|
||||||
Simplified the proxy mechanism. The proxy cache directory (/proxy) can now be removed [annando]
|
Simplified the proxy mechanism. The proxy cache directory (/proxy) can now be removed [annando]
|
||||||
DFRN is now always handled with the Diaspora transport layer. The legacy DFRN transport layer is removed [annando]
|
DFRN is now always handled with the Diaspora transport layer. The legacy DFRN transport layer is removed [annando]
|
||||||
|
Legacy OAuth server is removed [annando]
|
||||||
|
|
||||||
Version 2021.07 (2021-07-04)
|
Version 2021.07 (2021-07-04)
|
||||||
Friendica Core
|
Friendica Core
|
||||||
|
|
|
@ -30,8 +30,6 @@ These endpoints use the [Friendica API entities](help/API-Entities).
|
||||||
- POST api/friendships/destroy
|
- POST api/friendships/destroy
|
||||||
- GET api/friends/ids
|
- GET api/friends/ids
|
||||||
- GET/POST api/help/test
|
- GET/POST api/help/test
|
||||||
- POST api/oauth/access_token
|
|
||||||
- POST api/oauth/request_token
|
|
||||||
- GET api/search
|
- GET api/search
|
||||||
- GET api/statuses/show/:id
|
- GET api/statuses/show/:id
|
||||||
- POST api/statuses/destroy/:id
|
- POST api/statuses/destroy/:id
|
||||||
|
@ -67,6 +65,8 @@ These endpoints use the [Friendica API entities](help/API-Entities).
|
||||||
- blocks/exists
|
- blocks/exists
|
||||||
- blocks/blocking
|
- blocks/blocking
|
||||||
- oauth/authorize
|
- oauth/authorize
|
||||||
|
- oauth/access_token
|
||||||
|
- oauth/request_token
|
||||||
- statusnet/groups/timeline
|
- statusnet/groups/timeline
|
||||||
- statusnet/groups/show
|
- statusnet/groups/show
|
||||||
- statusnet/groups/create
|
- statusnet/groups/create
|
||||||
|
|
|
@ -93,9 +93,11 @@ These endpoints use the [Mastodon API entities](https://docs.joinmastodon.org/en
|
||||||
- [`POST /api/v1/notifications/clear`](https://docs.joinmastodon.org/methods/notifications/)
|
- [`POST /api/v1/notifications/clear`](https://docs.joinmastodon.org/methods/notifications/)
|
||||||
- [`POST /api/v1/notifications/:id/dismiss`](https://docs.joinmastodon.org/methods/notifications/)
|
- [`POST /api/v1/notifications/:id/dismiss`](https://docs.joinmastodon.org/methods/notifications/)
|
||||||
- [`GET /api/v1/preferences`](https://docs.joinmastodon.org/methods/accounts/preferences/)
|
- [`GET /api/v1/preferences`](https://docs.joinmastodon.org/methods/accounts/preferences/)
|
||||||
|
- [`GET /api/v1/search`](https://docs.joinmastodon.org/methods/search/)
|
||||||
- [`POST /api/v1/statuses`](https://docs.joinmastodon.org/methods/statuses/)
|
- [`POST /api/v1/statuses`](https://docs.joinmastodon.org/methods/statuses/)
|
||||||
- [`GET /api/v1/statuses/:id`](https://docs.joinmastodon.org/methods/statuses/)
|
- [`GET /api/v1/statuses/:id`](https://docs.joinmastodon.org/methods/statuses/)
|
||||||
- [`DELETE /api/v1/statuses/:id`](https://docs.joinmastodon.org/methods/statuses/)
|
- [`DELETE /api/v1/statuses/:id`](https://docs.joinmastodon.org/methods/statuses/)
|
||||||
|
- [`GET /api/v1/statuses/:id/card`](https://docs.joinmastodon.org/methods/statuses/)
|
||||||
- [`GET /api/v1/statuses/:id/context`](https://docs.joinmastodon.org/methods/statuses/)
|
- [`GET /api/v1/statuses/:id/context`](https://docs.joinmastodon.org/methods/statuses/)
|
||||||
- [`GET /api/v1/statuses/:id/reblogged_by`](https://docs.joinmastodon.org/methods/statuses/)
|
- [`GET /api/v1/statuses/:id/reblogged_by`](https://docs.joinmastodon.org/methods/statuses/)
|
||||||
- [`GET /api/v1/statuses/:id/favourited_by`](https://docs.joinmastodon.org/methods/statuses/)
|
- [`GET /api/v1/statuses/:id/favourited_by`](https://docs.joinmastodon.org/methods/statuses/)
|
||||||
|
|
|
@ -619,10 +619,6 @@ Here is a complete list of all hook callbacks with file locations (as of 24-Sep-
|
||||||
|
|
||||||
Hook::callAll('jot_tool', $jotplugins);
|
Hook::callAll('jot_tool', $jotplugins);
|
||||||
|
|
||||||
### src/Network/FKOAuth1.php
|
|
||||||
|
|
||||||
Hook::callAll('logged_in', $a->user);
|
|
||||||
|
|
||||||
### src/Render/FriendicaSmartyEngine.php
|
### src/Render/FriendicaSmartyEngine.php
|
||||||
|
|
||||||
Hook::callAll("template_vars", $arr);
|
Hook::callAll("template_vars", $arr);
|
||||||
|
|
|
@ -20,9 +20,7 @@ Using an invalid method results in HTTP error 405 "Method Not Allowed".
|
||||||
|
|
||||||
### Authentication
|
### Authentication
|
||||||
|
|
||||||
Friendica supports basic HTTP Auth and OAuth 1 to authenticate the user to the APIs.
|
Friendica supports basic HTTP Auth and OAuth to authenticate the user to the APIs.
|
||||||
|
|
||||||
OAuth settings can be added by the user in web UI under [/settings/oauth/](/settings/oauth/).
|
|
||||||
|
|
||||||
### Errors
|
### Errors
|
||||||
|
|
||||||
|
|
|
@ -174,7 +174,7 @@ function api_register_func($path, $func, $auth = false, $method = API_METHOD_ANY
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log in user via OAuth1 or Simple HTTP Auth.
|
* Log in user via Simple HTTP Auth.
|
||||||
* Simple Auth allow username in form of <pre>user@server</pre>, ignoring server part
|
* Simple Auth allow username in form of <pre>user@server</pre>, ignoring server part
|
||||||
*
|
*
|
||||||
* @param App $a App
|
* @param App $a App
|
||||||
|
|
|
@ -79,7 +79,7 @@ class Status extends BaseFactory
|
||||||
'thr-parent-id', 'parent-author-id', 'language', 'uri', 'plink', 'private', 'vid', 'gravity'];
|
'thr-parent-id', 'parent-author-id', 'language', 'uri', 'plink', 'private', 'vid', 'gravity'];
|
||||||
$item = Post::selectFirst($fields, ['uri-id' => $uriId, 'uid' => [0, $uid]], ['order' => ['uid' => true]]);
|
$item = Post::selectFirst($fields, ['uri-id' => $uriId, 'uid' => [0, $uid]], ['order' => ['uid' => true]]);
|
||||||
if (!$item) {
|
if (!$item) {
|
||||||
throw new HTTPException\NotFoundException('Item with URI ID ' . $uriId . 'not found' . ($uid ? ' for user ' . $uid : '.'));
|
throw new HTTPException\NotFoundException('Item with URI ID ' . $uriId . ' not found' . ($uid ? ' for user ' . $uid : '.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$account = $this->mstdnAccountFactory->createFromContactId($item['author-id']);
|
$account = $this->mstdnAccountFactory->createFromContactId($item['author-id']);
|
||||||
|
|
|
@ -74,7 +74,7 @@ class Search extends BaseApi
|
||||||
$result['statuses'] = self::searchStatuses($uid, $request['q'], $request['account_id'], $request['max_id'], $request['min_id'], $limit, $request['offset']);
|
$result['statuses'] = self::searchStatuses($uid, $request['q'], $request['account_id'], $request['max_id'], $request['min_id'], $limit, $request['offset']);
|
||||||
}
|
}
|
||||||
if ((empty($request['type']) || ($request['type'] == 'hashtags')) && (strpos($request['q'], '@') == false)) {
|
if ((empty($request['type']) || ($request['type'] == 'hashtags')) && (strpos($request['q'], '@') == false)) {
|
||||||
$result['hashtags'] = self::searchHashtags($request['q'], $request['exclude_unreviewed'], $limit, $request['offset']);
|
$result['hashtags'] = self::searchHashtags($request['q'], $request['exclude_unreviewed'], $limit, $request['offset'], $parameters['version']);
|
||||||
}
|
}
|
||||||
|
|
||||||
System::jsonExit($result);
|
System::jsonExit($result);
|
||||||
|
@ -175,7 +175,7 @@ class Search extends BaseApi
|
||||||
return $statuses;
|
return $statuses;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function searchHashtags(string $q, bool $exclude_unreviewed, int $limit, int $offset)
|
private static function searchHashtags(string $q, bool $exclude_unreviewed, int $limit, int $offset, int $version)
|
||||||
{
|
{
|
||||||
$q = ltrim($q, '#');
|
$q = ltrim($q, '#');
|
||||||
|
|
||||||
|
@ -187,7 +187,11 @@ class Search extends BaseApi
|
||||||
|
|
||||||
$hashtags = [];
|
$hashtags = [];
|
||||||
foreach ($tags as $tag) {
|
foreach ($tags as $tag) {
|
||||||
$hashtags[] = new \Friendica\Object\Api\Mastodon\Tag(DI::baseUrl(), $tag);
|
if ($version == 1) {
|
||||||
|
$hashtags[] = $tag['name'];
|
||||||
|
} else {
|
||||||
|
$hashtags[] = new \Friendica\Object\Api\Mastodon\Tag(DI::baseUrl(), $tag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $hashtags;
|
return $hashtags;
|
||||||
|
|
57
src/Module/Api/Mastodon/Statuses/Card.php
Normal file
57
src/Module/Api/Mastodon/Statuses/Card.php
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (C) 2010-2021, the Friendica project
|
||||||
|
*
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Friendica\Module\Api\Mastodon\Statuses;
|
||||||
|
|
||||||
|
use Friendica\Core\System;
|
||||||
|
use Friendica\DI;
|
||||||
|
use Friendica\Model\Post;
|
||||||
|
use Friendica\Module\BaseApi;
|
||||||
|
use Friendica\Network\HTTPException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see https://docs.joinmastodon.org/methods/statuses/
|
||||||
|
*/
|
||||||
|
class Card extends BaseApi
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param array $parameters
|
||||||
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
|
*/
|
||||||
|
public static function rawContent(array $parameters = [])
|
||||||
|
{
|
||||||
|
$uid = self::getCurrentUserID();
|
||||||
|
|
||||||
|
if (empty($parameters['id'])) {
|
||||||
|
DI::mstdnError()->UnprocessableEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = $parameters['id'];
|
||||||
|
|
||||||
|
if (!Post::exists(['uri-id' => $id, 'uid' => [0, $uid]])) {
|
||||||
|
throw new HTTPException\NotFoundException('Item with URI ID ' . $id . ' not found' . ($uid ? ' for user ' . $uid : '.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$card = DI::mstdnCard()->createFromUriId($id);
|
||||||
|
|
||||||
|
System::jsonExit($card->toArray());
|
||||||
|
}
|
||||||
|
}
|
|
@ -131,6 +131,7 @@ return [
|
||||||
'/scheduled_statuses/{id:\d+}' => [Module\Api\Mastodon\Unimplemented::class, [R::GET, R::PUT, R::DELETE]], // not supported
|
'/scheduled_statuses/{id:\d+}' => [Module\Api\Mastodon\Unimplemented::class, [R::GET, R::PUT, R::DELETE]], // not supported
|
||||||
'/statuses' => [Module\Api\Mastodon\Statuses::class, [ R::POST]],
|
'/statuses' => [Module\Api\Mastodon\Statuses::class, [ R::POST]],
|
||||||
'/statuses/{id:\d+}' => [Module\Api\Mastodon\Statuses::class, [R::GET, R::DELETE]],
|
'/statuses/{id:\d+}' => [Module\Api\Mastodon\Statuses::class, [R::GET, R::DELETE]],
|
||||||
|
'/statuses/{id:\d+}/card' => [Module\Api\Mastodon\Statuses\Card::class, [R::GET ]],
|
||||||
'/statuses/{id:\d+}/context' => [Module\Api\Mastodon\Statuses\Context::class, [R::GET ]],
|
'/statuses/{id:\d+}/context' => [Module\Api\Mastodon\Statuses\Context::class, [R::GET ]],
|
||||||
'/statuses/{id:\d+}/reblogged_by' => [Module\Api\Mastodon\Statuses\RebloggedBy::class, [R::GET ]],
|
'/statuses/{id:\d+}/reblogged_by' => [Module\Api\Mastodon\Statuses\RebloggedBy::class, [R::GET ]],
|
||||||
'/statuses/{id:\d+}/favourited_by' => [Module\Api\Mastodon\Statuses\FavouritedBy::class, [R::GET ]],
|
'/statuses/{id:\d+}/favourited_by' => [Module\Api\Mastodon\Statuses\FavouritedBy::class, [R::GET ]],
|
||||||
|
@ -154,7 +155,7 @@ return [
|
||||||
'/timelines/tag/{hashtag}' => [Module\Api\Mastodon\Timelines\Tag::class, [R::GET ]],
|
'/timelines/tag/{hashtag}' => [Module\Api\Mastodon\Timelines\Tag::class, [R::GET ]],
|
||||||
'/trends' => [Module\Api\Mastodon\Trends::class, [R::GET ]],
|
'/trends' => [Module\Api\Mastodon\Trends::class, [R::GET ]],
|
||||||
],
|
],
|
||||||
'/v2' => [
|
'/v{version:\d+}' => [
|
||||||
'/search' => [Module\Api\Mastodon\Search::class, [R::GET ]],
|
'/search' => [Module\Api\Mastodon\Search::class, [R::GET ]],
|
||||||
],
|
],
|
||||||
'/friendica' => [
|
'/friendica' => [
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
<h1>{{$title}}</h1>
|
|
||||||
|
|
||||||
<p>{{$info}}</p>
|
|
||||||
<code>{{$code}}</code>
|
|
|
@ -1,18 +0,0 @@
|
||||||
|
|
||||||
<h1>{{$title}}</h1>
|
|
||||||
|
|
||||||
<form method="POST">
|
|
||||||
<input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
|
|
||||||
|
|
||||||
{{include file="field_input.tpl" field=$name}}
|
|
||||||
{{include file="field_input.tpl" field=$key}}
|
|
||||||
{{include file="field_input.tpl" field=$secret}}
|
|
||||||
{{include file="field_input.tpl" field=$redirect}}
|
|
||||||
{{include file="field_input.tpl" field=$icon}}
|
|
||||||
|
|
||||||
<div class="settings-submit-wrapper">
|
|
||||||
<input type="submit" name="submit" class="settings-submit" value="{{$submit}}" />
|
|
||||||
<!-- <input type="submit" name="cancel" class="settings-submit" value="{{$cancel}}" /> -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
|
@ -1,19 +0,0 @@
|
||||||
<div class="generic-page-wrapper">
|
|
||||||
<h2 class="heading">{{$title}}</h2>
|
|
||||||
|
|
||||||
<form method="POST">
|
|
||||||
<input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
|
|
||||||
|
|
||||||
{{include file="field_input.tpl" field=$name}}
|
|
||||||
{{include file="field_input.tpl" field=$key}}
|
|
||||||
{{include file="field_input.tpl" field=$secret}}
|
|
||||||
{{include file="field_input.tpl" field=$redirect}}
|
|
||||||
{{include file="field_input.tpl" field=$icon}}
|
|
||||||
|
|
||||||
<div class="form-group pull-right settings-submit-wrapper">
|
|
||||||
<button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button>
|
|
||||||
</div>
|
|
||||||
<div class="clear"></div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
Loading…
Reference in a new issue