OAuth connections now have to be ackknowledged

This commit is contained in:
Michael 2021-05-12 06:50:27 +00:00
parent c22846339a
commit 6ca42512e9
4 changed files with 85 additions and 7 deletions

View file

@ -218,7 +218,17 @@ class BaseApi extends BaseModule
return $application; return $application;
} }
public static function existsTokenForUser(array $application, int $uid)
{
return DBA::exists('application-token', ['application-id' => $application['id'], 'uid' => $uid]);
}
public static function getTokenForUser(array $application, int $uid) public static function getTokenForUser(array $application, int $uid)
{
return DBA::selectFirst('application-token', [], ['application-id' => $application['id'], 'uid' => $uid]);
}
public static function createTokenForUser(array $application, int $uid)
{ {
$code = bin2hex(random_bytes(32)); $code = bin2hex(random_bytes(32));
$access_token = bin2hex(random_bytes(32)); $access_token = bin2hex(random_bytes(32));
@ -230,6 +240,7 @@ class BaseApi extends BaseModule
return DBA::selectFirst('application-token', [], ['application-id' => $application['id'], 'uid' => $uid]); return DBA::selectFirst('application-token', [], ['application-id' => $application['id'], 'uid' => $uid]);
} }
/** /**
* Get user info array. * Get user info array.
* *

View file

@ -0,0 +1,55 @@
<?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\OAuth;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
use Friendica\DI;
use Friendica\Module\BaseApi;
/**
* Dummy class for all currently unimplemented endpoints
*/
class Acknowledge extends BaseApi
{
public static function post(array $parameters = [])
{
DI::session()->set('oauth_acknowledge', true);
DI::app()->redirect(DI::session()->get('return_path'));
}
public static function content(array $parameters = [])
{
DI::session()->set('return_path', $_REQUEST['return_path'] ?? '');
$tpl = Renderer::getMarkupTemplate('oauth_authorize.tpl');
$o = Renderer::replaceMacros($tpl, [
'$title' => DI::l10n()->t('Authorize application connection'),
'$app' => ['name' => $_REQUEST['application'] ?? ''],
'$authorize' => DI::l10n()->t('Do you want to authorize this application to access your posts and contacts, and/or create new posts for you?'),
'$yes' => DI::l10n()->t('Yes'),
'$no' => DI::l10n()->t('No'),
]);
return $o;
}
}

View file

@ -47,17 +47,24 @@ class Authorize extends BaseApi
DI::mstdnError()->RecordNotFound(); DI::mstdnError()->RecordNotFound();
} }
$request = $_REQUEST;
unset($request['pagename']);
$redirect = urlencode('oauth/authorize?' . http_build_query($request));
$uid = local_user(); $uid = local_user();
if (empty($uid)) { if (empty($uid)) {
Logger::info('Redirect to login'); Logger::info('Redirect to login');
$request = $_REQUEST; DI::app()->redirect('login?return_path=' . $redirect);
unset($request['pagename']);
DI::app()->redirect('login?return_path=' . urlencode('/oauth/authorize?' . http_build_query($request)));
} else { } else {
Logger::info('Already logged in user', ['uid' => $uid]); Logger::info('Already logged in user', ['uid' => $uid]);
} }
$token = self::getTokenForUser($application, $uid); if (!self::existsTokenForUser($application, $uid) && !DI::session()->get('oauth_acknowledge')) {
Logger::info('Redirect to acknowledge');
DI::app()->redirect('oauth/acknowledge?return_path=' . $redirect);
}
$token = self::createTokenForUser($application, $uid);
if (!$token) { if (!$token) {
DI::mstdnError()->RecordNotFound(); DI::mstdnError()->RecordNotFound();
} }

View file

@ -331,9 +331,14 @@ return [
'/mark/all' => [Module\Notifications\Notification::class, [R::GET]], '/mark/all' => [Module\Notifications\Notification::class, [R::GET]],
'/{id:\d+}' => [Module\Notifications\Notification::class, [R::GET, R::POST]], '/{id:\d+}' => [Module\Notifications\Notification::class, [R::GET, R::POST]],
], ],
'/oauth/authorize' => [Module\OAuth\Authorize::class, [R::GET]],
'/oauth/revoke' => [Module\OAuth\Revoke::class, [R::POST]], '/oauth' => [
'/oauth/token' => [Module\OAuth\Token::class, [R::POST]], '/acknowledge' => [Module\OAuth\Acknowledge::class, [R::GET, R::POST]],
'/authorize' => [Module\OAuth\Authorize::class, [R::GET]],
'/revoke' => [Module\OAuth\Revoke::class, [R::POST]],
'/token' => [Module\OAuth\Token::class, [R::POST]],
],
'/objects/{guid}[/{activity}]' => [Module\Objects::class, [R::GET]], '/objects/{guid}[/{activity}]' => [Module\Objects::class, [R::GET]],
'/oembed' => [ '/oembed' => [