aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorernolf <raphael.gradenwitz@googlemail.com>2024-08-15 20:46:46 +0200
committerJoas Schilling <213943+nickvergessen@users.noreply.github.com>2024-09-28 08:06:24 +0200
commitb4ea146d10506f125c103706026965fc9c1b45ef (patch)
treece9b3a17056645fd9b270a7b0c342e41ff921ba8 /lib
parente202b6c460f35e38a3ece4009562ae618061bf1e (diff)
downloadnextcloud-server-b4ea146d10506f125c103706026965fc9c1b45ef.tar.gz
nextcloud-server-b4ea146d10506f125c103706026965fc9c1b45ef.zip
feat(share): make sharelink token length configurableernolf/configurable_sharetoken_length
- ensure unique share token with dynamic length adjustment Signed-off-by: ernolf <raphael.gradenwitz@googlemail.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/private/Share/Constants.php5
-rw-r--r--lib/private/Share/Helper.php9
-rw-r--r--lib/private/Share20/Manager.php44
3 files changed, 50 insertions, 8 deletions
diff --git a/lib/private/Share/Constants.php b/lib/private/Share/Constants.php
index 8cfa83f9ea2..baff04fbc4a 100644
--- a/lib/private/Share/Constants.php
+++ b/lib/private/Share/Constants.php
@@ -63,7 +63,10 @@ class Constants {
public const RESPONSE_FORMAT = 'json'; // default response format for ocs calls
- public const TOKEN_LENGTH = 15; // old (oc7) length is 32, keep token length in db at least that for compatibility
+ public const MIN_TOKEN_LENGTH = 6; // 19,770,609,664 different possible variations
+ public const DEFAULT_TOKEN_LENGTH = 15; // 54,960,434,128,018,667,122,720,768 different possible variations
+ public const MAX_TOKEN_LENGTH = 32; // 8,167,835,760,036,914,488,254,418,108,462,708,901,695,678,621,570,564,096 different possible variations
+ public const TOKEN_LENGTH = self::DEFAULT_TOKEN_LENGTH; // old (oc7) length is 32, keep token length in db at least that for compatibility
protected static $shareTypeUserAndGroups = -1;
protected static $shareTypeGroupUserUnique = 2;
diff --git a/lib/private/Share/Helper.php b/lib/private/Share/Helper.php
index 76e7daeb9e5..d53f9d6ed94 100644
--- a/lib/private/Share/Helper.php
+++ b/lib/private/Share/Helper.php
@@ -126,4 +126,13 @@ class Helper extends \OC\Share\Constants {
return false;
}
+
+ public static function getTokenLength(): int {
+ $config = \OCP\Server::get(\OCP\IAppConfig::class);
+ $tokenLength = $config->getValueInt('core', 'shareapi_token_length', self::DEFAULT_TOKEN_LENGTH);
+ $tokenLength = $tokenLength ?: self::DEFAULT_TOKEN_LENGTH;
+
+ // Token length should be within the defined min and max limits
+ return max(self::MIN_TOKEN_LENGTH, min($tokenLength, self::MAX_TOKEN_LENGTH));
+ }
}
diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php
index 1477560c6fd..f46d163e58a 100644
--- a/lib/private/Share20/Manager.php
+++ b/lib/private/Share20/Manager.php
@@ -656,13 +656,43 @@ class Manager implements IManager {
$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
- )
- );
+ // Initial token length
+ $tokenLength = \OC\Share\Helper::getTokenLength();
+
+ do {
+ $tokenExists = false;
+
+ for ($i = 0; $i <= 2; $i++) {
+ // Generate a new token
+ $token = $this->secureRandom->generate(
+ $tokenLength,
+ \OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
+ );
+
+ try {
+ // Try to fetch a share with the generated token
+ $this->getShareByToken($token);
+ $tokenExists = true; // Token exists, we need to try again
+ } catch (\OCP\Share\Exceptions\ShareNotFound $e) {
+ // Token is unique, exit the loop
+ $tokenExists = false;
+ break;
+ }
+ }
+
+ // If we've reached the maximum attempts and the token still exists, increase the token length
+ if ($tokenExists) {
+ $tokenLength++;
+
+ // Check if the token length exceeds the maximum allowed length
+ if ($tokenLength > \OC\Share\Constants::MAX_TOKEN_LENGTH) {
+ throw new \Exception('Unable to generate a unique share token. Maximum token length exceeded.');
+ }
+ }
+ } while ($tokenExists);
+
+ // Set the unique token
+ $share->setToken($token);
// Verify the expiration date
$share = $this->validateExpirationDateLink($share);