diff --git a/src/Module/OAuth/Authorize.php b/src/Module/OAuth/Authorize.php index b2792c598f..cf5187d947 100644 --- a/src/Module/OAuth/Authorize.php +++ b/src/Module/OAuth/Authorize.php @@ -41,11 +41,12 @@ class Authorize extends BaseApi public static function rawContent(array $parameters = []) { $request = self::getRequest([ - 'response_type' => '', - 'client_id' => '', + '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. 'client_secret' => '', // Isn't normally provided. We will use it if present. - 'redirect_uri' => '', - 'scope' => 'read', + '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 authorization code will be shown instead. Must match one of the redirect URIs declared during app registration. + 'scope' => 'read', // List of requested OAuth scopes, separated by spaces (or by pluses, if using query parameters). Must be a subset of scopes declared during app registration. If not provided, defaults to "read". 'state' => '', ]); diff --git a/src/Module/OAuth/Revoke.php b/src/Module/OAuth/Revoke.php index c641932437..519e79db01 100644 --- a/src/Module/OAuth/Revoke.php +++ b/src/Module/OAuth/Revoke.php @@ -21,6 +21,10 @@ namespace Friendica\Module\OAuth; +use Friendica\Core\Logger; +use Friendica\Core\System; +use Friendica\Database\DBA; +use Friendica\DI; use Friendica\Module\BaseApi; /** @@ -30,6 +34,20 @@ class Revoke extends BaseApi { public static function post(array $parameters = []) { - self::unsupported('post'); + $request = self::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 + ]); + + $condition = ['client_id' => $request['client_id'], 'client_secret' => $request['client_secret'], 'access_token' => $request['token']]; + $token = DBA::selectFirst('application-view', ['id'], $condition); + if (empty($token['id'])) { + Logger::warning('Token not found', $condition); + DI::mstdnError()->Unauthorized(); + } + + DBA::delete('application-token', ['application-id' => $token['id']]); + System::jsonExit([]); } } diff --git a/src/Module/OAuth/Token.php b/src/Module/OAuth/Token.php index 3a8be825ff..f104e96721 100644 --- a/src/Module/OAuth/Token.php +++ b/src/Module/OAuth/Token.php @@ -37,16 +37,23 @@ class Token extends BaseApi public static function post(array $parameters = []) { $request = self::getRequest([ - 'grant_type' => '', - 'code' => '', - 'redirect_uri' => '', - 'client_id' => '', - 'client_secret' => '', + '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. + 'scope' => 'read', // List of requested OAuth scopes, separated by spaces. Must be a subset of scopes declared during app registration. If not provided, defaults to "read". + 'code' => '', // A user authorization code, obtained via /oauth/authorize + 'grant_type' => '', // Set equal to "authorization_code" if code is provided in order to gain user-level access. Otherwise, set equal to "client_credentials" to obtain app-level access only. ]); // AndStatus transmits the client data in the AUTHORIZATION header field, see https://github.com/andstatus/andstatus/issues/530 - if (empty($request['client_id']) && !empty($_SERVER['HTTP_AUTHORIZATION']) && (substr($_SERVER['HTTP_AUTHORIZATION'], 0, 6) == 'Basic ')) { - $datapair = explode(':', base64_decode(trim(substr($_SERVER['HTTP_AUTHORIZATION'], 6)))); + $authorization = $_SERVER['HTTP_AUTHORIZATION'] ?? ''; + if (empty($authorization)) { + // workaround for HTTP-auth in CGI mode + $authorization = $_SERVER['REDIRECT_REMOTE_USER'] ?? ''; + } + + if (empty($request['client_id']) && substr($authorization, 0, 6) == 'Basic ') { + $datapair = explode(':', base64_decode(trim(substr($authorization, 6)))); if (count($datapair) == 2) { $request['client_id'] = $datapair[0]; $request['client_secret'] = $datapair[1]; diff --git a/src/Security/BasicAuth.php b/src/Security/BasicAuth.php index b76073e8b3..070c6500d3 100644 --- a/src/Security/BasicAuth.php +++ b/src/Security/BasicAuth.php @@ -124,7 +124,7 @@ class BasicAuth // workaround for HTTP-auth in CGI mode if (!empty($_SERVER['REDIRECT_REMOTE_USER'])) { $userpass = base64_decode(substr($_SERVER["REDIRECT_REMOTE_USER"], 6)); - if (strlen($userpass)) { + if (!empty($userpass) && strpos($userpass, ':')) { list($name, $password) = explode(':', $userpass); $_SERVER['PHP_AUTH_USER'] = $name; $_SERVER['PHP_AUTH_PW'] = $password; diff --git a/src/Security/OAuth.php b/src/Security/OAuth.php index 7210df8c2e..2f5dd39641 100644 --- a/src/Security/OAuth.php +++ b/src/Security/OAuth.php @@ -83,6 +83,11 @@ class OAuth { $authorization = $_SERVER['HTTP_AUTHORIZATION'] ?? ''; + if (empty($authorization)) { + // workaround for HTTP-auth in CGI mode + $authorization = $_SERVER['REDIRECT_REMOTE_USER'] ?? ''; + } + if (substr($authorization, 0, 7) != 'Bearer ') { return []; }