From 5dd1f7279f2ad89913734083a09c8715bbe4701b Mon Sep 17 00:00:00 2001 From: Daniel Jakob Date: Fri, 2 Feb 2024 00:33:57 +0100 Subject: [PATCH] Allow the user api method to return the current user info (#3807) If a user uses the Api via Api-Key, the user name of the user is not known. Api methods that require the specification of a user name cannot be used in this way. This change allows the `username` parameter to be omitted and in this case returns all the information of the currently used API user - including the username. --- docs/API-JSON-methods.md | 6 ++-- docs/API-XML-methods.md | 6 ++-- phpstan-baseline.neon | 5 ---- src/Module/Api/Method/UserMethod.php | 44 ++++++++++++++++------------ 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/docs/API-JSON-methods.md b/docs/API-JSON-methods.md index 6277a8abfd..f6d432844c 100644 --- a/docs/API-JSON-methods.md +++ b/docs/API-JSON-methods.md @@ -2814,11 +2814,13 @@ This takes a url and returns the song object in question ### user -This gets a user's public information +This gets a user's public information. + +If the username is omitted, this will return the current api user's public information. | Input | Type | Description | Optional | |------------|--------|-------------------------------------|---------:| -| 'username' | string | Username of the user to get details | NO | +| 'username' | string | Username of the user to get details | YES | * return array diff --git a/docs/API-XML-methods.md b/docs/API-XML-methods.md index 51460a950d..0e850125c0 100644 --- a/docs/API-XML-methods.md +++ b/docs/API-XML-methods.md @@ -2898,11 +2898,13 @@ This takes a url and returns the song object in question ### user -This gets a user's public information +This gets a user's public information. + +If the username is omitted, this will return the current api user's public information. | Input | Type | Description | Optional | |------------|--------|-----------------------------------------|---------:| -| 'username' | string | Username of the user to get details for | NO | +| 'username' | string | Username of the user to get details for | YES | * return diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 01b80a83c9..5202c1d47f 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -3225,11 +3225,6 @@ parameters: count: 1 path: src/Module/Api/Method/UserEditMethod.php - - - message: "#^Method Ampache\\\\Module\\\\Api\\\\Method\\\\UserMethod\\:\\:user\\(\\) has parameter \\$input with no value type specified in iterable type array\\.$#" - count: 1 - path: src/Module/Api/Method/UserMethod.php - - message: "#^Method Ampache\\\\Module\\\\Api\\\\Method\\\\UserPreferenceMethod\\:\\:user_preference\\(\\) has parameter \\$input with no value type specified in iterable type array\\.$#" count: 1 diff --git a/src/Module/Api/Method/UserMethod.php b/src/Module/Api/Method/UserMethod.php index 83b609160c..0157dbf503 100644 --- a/src/Module/Api/Method/UserMethod.php +++ b/src/Module/Api/Method/UserMethod.php @@ -26,6 +26,7 @@ namespace Ampache\Module\Api\Method; use Ampache\Module\Api\Exception\ErrorCodeEnum; +use Ampache\Module\Authorization\AccessLevelEnum; use Ampache\Repository\Model\User; use Ampache\Module\Api\Api; use Ampache\Module\Api\Json_Data; @@ -47,32 +48,37 @@ final class UserMethod * This get a user's public information * * username = (string) $username + * + * @param array{ + * username?: scalar, + * api_format: string + * } $input */ public static function user(array $input, User $user): bool { - if (!Api::check_parameter($input, array('username'), self::ACTION)) { - return false; - } - $username = (string) $input['username']; - if (empty($username)) { - debug_event(self::class, 'User `' . $username . '` cannot be found.', 1); - /* HINT: Requested object string/id/type ("album", "myusername", "some song title", 1298376) */ - Api::error(sprintf(T_('Not Found: %s'), $username), ErrorCodeEnum::NOT_FOUND, self::ACTION, 'username', $input['api_format']); + $username = $input['username'] ?? null; - return false; - } + // if the username is omitted, use the current users context to retrieve its own data + if ($username === null) { + $check_user = $user; - $check_user = User::get_from_username($username); - $valid = ($check_user instanceof User && $check_user->isNew() === false && in_array($check_user->id, static::getUserRepository()->getValid(true))); - if (!$valid) { - /* HINT: Requested object string/id/type ("album", "myusername", "some song title", 1298376) */ - Api::error(sprintf(T_('Not Found: %s'), $username), ErrorCodeEnum::NOT_FOUND, self::ACTION, 'username', $input['api_format']); + $fullinfo = true; + } else { + $userRepository = self::getUserRepository(); + $check_user = $userRepository->findByUsername((string) $username); + if ( + $check_user === null || + !in_array($check_user->getId(), $userRepository->getValid(true)) + ) { + /* HINT: Requested object string/id/type */ + Api::error(sprintf(T_('Not Found: %s'), $username), ErrorCodeEnum::NOT_FOUND, self::ACTION, 'username', $input['api_format']); - return false; - } + return false; + } - // get full info when you're an admin or searching for yourself - $fullinfo = (($check_user->id == $user->id) || ($user->access === 100)); + // get full info when you're an admin or searching for yourself + $fullinfo = $check_user->getId() === $user->getId() || $user->access === AccessLevelEnum::LEVEL_ADMIN; + } ob_end_clean(); switch ($input['api_format']) {