diff --git a/src/Module/BaseApi.php b/src/Module/BaseApi.php index a0139c637..d2240fcd6 100644 --- a/src/Module/BaseApi.php +++ b/src/Module/BaseApi.php @@ -218,7 +218,17 @@ class BaseApi extends BaseModule 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) + { + return DBA::selectFirst('application-token', [], ['application-id' => $application['id'], 'uid' => $uid]); + } + + public static function createTokenForUser(array $application, int $uid) { $code = 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]); } + /** * Get user info array. * diff --git a/src/Module/OAuth/Acknowledge.php b/src/Module/OAuth/Acknowledge.php new file mode 100644 index 000000000..617ab6c53 --- /dev/null +++ b/src/Module/OAuth/Acknowledge.php @@ -0,0 +1,55 @@ +. + * + */ + +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; + } +} diff --git a/src/Module/OAuth/Authorize.php b/src/Module/OAuth/Authorize.php index 8afc7d48a..4c2d9c027 100644 --- a/src/Module/OAuth/Authorize.php +++ b/src/Module/OAuth/Authorize.php @@ -47,17 +47,24 @@ class Authorize extends BaseApi DI::mstdnError()->RecordNotFound(); } + $request = $_REQUEST; + unset($request['pagename']); + $redirect = urlencode('oauth/authorize?' . http_build_query($request)); + $uid = local_user(); if (empty($uid)) { Logger::info('Redirect to login'); - $request = $_REQUEST; - unset($request['pagename']); - DI::app()->redirect('login?return_path=' . urlencode('/oauth/authorize?' . http_build_query($request))); + DI::app()->redirect('login?return_path=' . $redirect); } else { 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) { DI::mstdnError()->RecordNotFound(); } diff --git a/static/routes.config.php b/static/routes.config.php index f666feeff..9d8e1fda4 100644 --- a/static/routes.config.php +++ b/static/routes.config.php @@ -331,9 +331,14 @@ return [ '/mark/all' => [Module\Notifications\Notification::class, [R::GET]], '/{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/token' => [Module\OAuth\Token::class, [R::POST]], + + '/oauth' => [ + '/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]], '/oembed' => [