Skip to content

Commit

Permalink
Ampache/Subsonic: Case-insensitive user name checking
Browse files Browse the repository at this point in the history
In the normal log-in of ownCloud and Nextcloud, the user names are allowed
using any casing. The same is true at least for Ampache proper. Now also the
APIs of the Music app follow the suite.

refs owncloud#1147
  • Loading branch information
paulijar committed May 31, 2024
1 parent ab8f860 commit 6a60e0d
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
- Drop support for ownCloud versions older than 10.5.0 (i.e. OC 10.0 - 10.4)
- Drop support for Nextcloud versions older than 18 (i.e. NC 13 - 17)
- New design including cover art on all list-like views
- Ampache and Subsonic APIs: Check the username in case-insensitive manner
[#1147](https://github.com/owncloud/music/issues/1147)
- Ampache API:
* The action `download` doesn't implicitly record the track as played (unlike `stream`)
* The song property `url` refers to the `stream` URL instead of `download` URL
Expand Down
19 changes: 18 additions & 1 deletion lib/Db/AmpacheUserMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* @author Morris Jobke <[email protected]>
* @author Pauli Järvinen <[email protected]>
* @copyright Morris Jobke 2013, 2014
* @copyright Pauli Järvinen 2018 - 2023
* @copyright Pauli Järvinen 2018 - 2024
*/

namespace OCA\Music\Db;
Expand Down Expand Up @@ -58,6 +58,23 @@ public function getPasswordHash(int $id) : ?string {
return $row['hash'];
}

/**
* @param string $user Username, case-insensitive
* @return ?string Case-sensitively correct username, if the user has any API key(s)
*/
public function getProperUserId(string $user) : ?string {
$sql = 'SELECT `user_id` FROM `*PREFIX*music_ampache_users` WHERE LOWER(`user_id`) = LOWER(?)';
$params = [$user];
$result = $this->db->executeQuery($sql, $params);
$row = $result->fetch();

if ($row === false) {
return null;
}

return $row['user_id'];
}

public function getUserId(int $id) : ?string {
$sql = 'SELECT `user_id` FROM `*PREFIX*music_ampache_users` WHERE `id` = ?';
$params = [$id];
Expand Down
12 changes: 7 additions & 5 deletions lib/Middleware/AmpacheMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ private function handleHandshake(AmpacheController $controller) : void {
// year 2038 (or already in 2037 if the admin has configured close to the maximum expiry time).

$this->checkHandshakeTimestamp($timestamp, $currentTime);
$apiKeyId = $this->checkHandshakeAuthentication($user, $timestamp, $auth);
$session = $this->startNewSession($user, $expiryDate, $version, $apiKeyId);
$credentials = $this->checkHandshakeAuthentication($user, $timestamp, $auth);
$session = $this->startNewSession($credentials['user'], $expiryDate, $version, $credentials['apiKeyId']);
$controller->setSession($session);
}

Expand All @@ -113,18 +113,20 @@ private function checkHandshakeTimestamp(int $timestamp, int $currentTime) : voi
}
}

private function checkHandshakeAuthentication(?string $user, int $timestamp, ?string $auth) : int {
private function checkHandshakeAuthentication(?string $user, int $timestamp, ?string $auth) : array {
if ($user === null || $auth === null) {
throw new AmpacheException('Invalid Login - required credentials missing', 401);
}

$hashes = $this->ampacheUserMapper->getPasswordHashes($user);
$user = $this->ampacheUserMapper->getProperUserId($user);

$hashes = ($user !== null) ? $this->ampacheUserMapper->getPasswordHashes($user) : [];

foreach ($hashes as $keyId => $hash) {
$expectedHash = \hash('sha256', $timestamp . $hash);

if ($expectedHash === $auth) {
return (int)$keyId;
return ['user' => $user, 'apiKeyId' => (int)$keyId];
}
}

Expand Down
5 changes: 3 additions & 2 deletions lib/Middleware/SubsonicMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* later. See the COPYING file.
*
* @author Pauli Järvinen <[email protected]>
* @copyright Pauli Järvinen 2019, 2020
* @copyright Pauli Järvinen 2019 - 2024
*/

namespace OCA\Music\Middleware;
Expand Down Expand Up @@ -103,7 +103,8 @@ private function checkAuthentication(SubsonicController $controller) {
$pass = \hex2bin(\substr($pass, \strlen('enc:')));
}

if ($this->credentialsAreValid($user, $pass)) {
$user = $this->userMapper->getProperUserId($user);
if ($user !== null && $this->credentialsAreValid($user, $pass)) {
$controller->setAuthenticatedUser($user);
} else {
throw new SubsonicException('Invalid Login', 40);
Expand Down

0 comments on commit 6a60e0d

Please sign in to comment.