Skip to content

Commit

Permalink
feat(share): ensure unique share tokens with dynamic length adjustment
Browse files Browse the repository at this point in the history
- check for token collisions and retry up to three times.
- abort with an error if maximum token length is reached without finding a unique token.

Signed-off-by: ernolf <raphael.gradenwitz@googlemail.com>
  • Loading branch information
ernolf authored and nickvergessen committed Sep 17, 2024
1 parent e4f5d39 commit 33f7590
Showing 1 changed file with 29 additions and 7 deletions.
36 changes: 29 additions & 7 deletions lib/private/Share20/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -665,13 +665,35 @@ public function createShare(IShare $share) {
$this->linkCreateChecks($share);
$this->setLinkParent($share);

// For now ignore a set token.
$share->setToken(
$this->secureRandom->generate(
\OC\Share\Constants::TOKEN_LENGTH,
\OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
)
);
do {
$tokenExists = false;
$attempts = 0;

do {
// Generate a new token
$token = $this->secureRandom->generate(
\OC\Share\Constants::TOKEN_LENGTH,
\OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
);

try {
// Try to fetch a share with the generated token
$this->getShareByToken($token);
$tokenExists = true; // Token exists, generate a new one
$attempts++; // Increment the attempt counter
} catch (\OCP\Share\Exceptions\ShareNotFound $e) {
$tokenExists = false; // Token is unique, we can use it
}
} while ($tokenExists && $attempts < 3);

// If we've reached the maximum attempts and the token still exists, increase the token length
if ($tokenExists) {
throw new \Exception('Unable to generate a unique share token. Maximum token length exceeded.');
}
} while ($tokenExists);

Check failure on line 693 in lib/private/Share20/Manager.php

View workflow job for this annotation

GitHub Actions / static-code-analysis

TypeDoesNotContainType

lib/private/Share20/Manager.php:693:14: TypeDoesNotContainType: Type false for $tokenExists is always !falsy (see https://psalm.dev/056)

Check failure

Code scanning / Psalm

TypeDoesNotContainType Error

Type false for $tokenExists is always !falsy

// Set the unique token
$share->setToken($token);

// Verify the expiration date
$share = $this->validateExpirationDateLink($share);
Expand Down

0 comments on commit 33f7590

Please sign in to comment.