diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/composer/composer/autoload_classmap.php | 1 | ||||
-rw-r--r-- | lib/composer/composer/autoload_static.php | 1 | ||||
-rw-r--r-- | lib/l10n/et_EE.js | 10 | ||||
-rw-r--r-- | lib/l10n/et_EE.json | 10 | ||||
-rw-r--r-- | lib/l10n/lv.js | 12 | ||||
-rw-r--r-- | lib/l10n/lv.json | 12 | ||||
-rw-r--r-- | lib/private/AppConfig.php | 8 | ||||
-rw-r--r-- | lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php | 2 | ||||
-rw-r--r-- | lib/private/Security/Bruteforce/Throttler.php | 29 | ||||
-rw-r--r-- | lib/private/Setup.php | 2 | ||||
-rw-r--r-- | lib/private/Share20/DefaultShareProvider.php | 42 | ||||
-rw-r--r-- | lib/private/Share20/Manager.php | 13 | ||||
-rw-r--r-- | lib/public/Share/IShareProviderSupportsAllSharesInFolder.php | 24 |
13 files changed, 125 insertions, 41 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 177abfefe8e..b1c6c453b0a 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -780,6 +780,7 @@ return array( 'OCP\\Share\\IShareHelper' => $baseDir . '/lib/public/Share/IShareHelper.php', 'OCP\\Share\\IShareProvider' => $baseDir . '/lib/public/Share/IShareProvider.php', 'OCP\\Share\\IShareProviderSupportsAccept' => $baseDir . '/lib/public/Share/IShareProviderSupportsAccept.php', + 'OCP\\Share\\IShareProviderSupportsAllSharesInFolder' => $baseDir . '/lib/public/Share/IShareProviderSupportsAllSharesInFolder.php', 'OCP\\Share\\IShareProviderWithNotification' => $baseDir . '/lib/public/Share/IShareProviderWithNotification.php', 'OCP\\Share_Backend' => $baseDir . '/lib/public/Share_Backend.php', 'OCP\\Share_Backend_Collection' => $baseDir . '/lib/public/Share_Backend_Collection.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index ddccd0692ca..6eecb2da4b5 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -821,6 +821,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OCP\\Share\\IShareHelper' => __DIR__ . '/../../..' . '/lib/public/Share/IShareHelper.php', 'OCP\\Share\\IShareProvider' => __DIR__ . '/../../..' . '/lib/public/Share/IShareProvider.php', 'OCP\\Share\\IShareProviderSupportsAccept' => __DIR__ . '/../../..' . '/lib/public/Share/IShareProviderSupportsAccept.php', + 'OCP\\Share\\IShareProviderSupportsAllSharesInFolder' => __DIR__ . '/../../..' . '/lib/public/Share/IShareProviderSupportsAllSharesInFolder.php', 'OCP\\Share\\IShareProviderWithNotification' => __DIR__ . '/../../..' . '/lib/public/Share/IShareProviderWithNotification.php', 'OCP\\Share_Backend' => __DIR__ . '/../../..' . '/lib/public/Share_Backend.php', 'OCP\\Share_Backend_Collection' => __DIR__ . '/../../..' . '/lib/public/Share_Backend_Collection.php', diff --git a/lib/l10n/et_EE.js b/lib/l10n/et_EE.js index d882e0ee79e..d0ff1a1e511 100644 --- a/lib/l10n/et_EE.js +++ b/lib/l10n/et_EE.js @@ -279,6 +279,7 @@ OC.L10N.register( "Ensure there is a file called \"%1$s\" in the root of the data directory. It should have the content: \"%2$s\"" : "Palun taga, et andmete juurkaustas leidub fail „%1$s“, mille sisuks on „%2$s“", "Action \"%s\" not supported or implemented." : "„%s“ tegevus pole toetatud või implementeeritud.", "Parameters missing in order to complete the request. Missing Parameters: \"%s\"" : "Päringu lõpetamiseks on puudu järgmised parameetrid; „%s“", + "ID \"%1$s\" already used by cloud federation provider \"%2$s\"" : "„%1$s“ tunnus on juba kasutusel liitpilve serveris „%2$s“", "Cloud Federation Provider with ID: \"%s\" does not exist." : "Liitpilve teenusepakkujat tunnusega „%s“ pole olemas.", "Could not obtain lock type %d on \"%s\"." : "Ei suutnud hankida %d tüüpi lukustust asukohas „%s“.", "Storage unauthorized. %s" : "Andmeruum on autoriseerimata. %s", @@ -286,6 +287,12 @@ OC.L10N.register( "Storage connection error. %s" : "Viga andmeruumi ühenduse loomisel. %s", "Storage is temporarily not available" : "Salvestusruum pole ajutiselt kättesaadav", "Storage connection timeout. %s" : "Aegumine andmeruumi ühenduse loomisel. %s", + "Transcribe audio" : "Kirjuta heli üles", + "Transcribe the things said in an audio" : "Kirjuta üles helifailis kuuldav jutt", + "Audio input" : "Helisisend", + "The audio to transcribe" : "Üleskirjutatav helifail", + "Transcription" : "Üleskirjutus", + "The transcribed text" : "Üleskirjutatud tekst", "Generate image" : "Piltide loomine", "Generate an image from a text prompt" : "Loo tekstisisendist pilt", "Prompt" : "Sisendvorm", @@ -299,6 +306,9 @@ OC.L10N.register( "Write transcript that you want the assistant to generate speech from" : "Kirjuta üles see, mille alusel tahad Abilisel lasta koostada kõne", "Output speech" : "Kõneväljund", "The generated speech" : "Koostatud kõne", + "Chat" : "Vestle", + "Chat with the assistant" : "Vestle Abilisega", + "System prompt" : "Süsteemi viip", "Generate a headline" : "Alapealkirja loomine", "Generates a possible headline for a text." : "Võimaldab luua teksti põhjal kokkuvõtliku alapealkirja.", "Original text" : "Lähtetekst", diff --git a/lib/l10n/et_EE.json b/lib/l10n/et_EE.json index 295c4b77855..f42e00f28f1 100644 --- a/lib/l10n/et_EE.json +++ b/lib/l10n/et_EE.json @@ -277,6 +277,7 @@ "Ensure there is a file called \"%1$s\" in the root of the data directory. It should have the content: \"%2$s\"" : "Palun taga, et andmete juurkaustas leidub fail „%1$s“, mille sisuks on „%2$s“", "Action \"%s\" not supported or implemented." : "„%s“ tegevus pole toetatud või implementeeritud.", "Parameters missing in order to complete the request. Missing Parameters: \"%s\"" : "Päringu lõpetamiseks on puudu järgmised parameetrid; „%s“", + "ID \"%1$s\" already used by cloud federation provider \"%2$s\"" : "„%1$s“ tunnus on juba kasutusel liitpilve serveris „%2$s“", "Cloud Federation Provider with ID: \"%s\" does not exist." : "Liitpilve teenusepakkujat tunnusega „%s“ pole olemas.", "Could not obtain lock type %d on \"%s\"." : "Ei suutnud hankida %d tüüpi lukustust asukohas „%s“.", "Storage unauthorized. %s" : "Andmeruum on autoriseerimata. %s", @@ -284,6 +285,12 @@ "Storage connection error. %s" : "Viga andmeruumi ühenduse loomisel. %s", "Storage is temporarily not available" : "Salvestusruum pole ajutiselt kättesaadav", "Storage connection timeout. %s" : "Aegumine andmeruumi ühenduse loomisel. %s", + "Transcribe audio" : "Kirjuta heli üles", + "Transcribe the things said in an audio" : "Kirjuta üles helifailis kuuldav jutt", + "Audio input" : "Helisisend", + "The audio to transcribe" : "Üleskirjutatav helifail", + "Transcription" : "Üleskirjutus", + "The transcribed text" : "Üleskirjutatud tekst", "Generate image" : "Piltide loomine", "Generate an image from a text prompt" : "Loo tekstisisendist pilt", "Prompt" : "Sisendvorm", @@ -297,6 +304,9 @@ "Write transcript that you want the assistant to generate speech from" : "Kirjuta üles see, mille alusel tahad Abilisel lasta koostada kõne", "Output speech" : "Kõneväljund", "The generated speech" : "Koostatud kõne", + "Chat" : "Vestle", + "Chat with the assistant" : "Vestle Abilisega", + "System prompt" : "Süsteemi viip", "Generate a headline" : "Alapealkirja loomine", "Generates a possible headline for a text." : "Võimaldab luua teksti põhjal kokkuvõtliku alapealkirja.", "Original text" : "Lähtetekst", diff --git a/lib/l10n/lv.js b/lib/l10n/lv.js index e5b635a2bd3..c6eeeaa756c 100644 --- a/lib/l10n/lv.js +++ b/lib/l10n/lv.js @@ -31,14 +31,14 @@ OC.L10N.register( "View profile" : "Skatīt profilu", "today" : "šodien", "yesterday" : "vakar", - "_%n day ago_::_%n days ago_" : ["%n dienas atpakaļ","%n dienas atpakaļ","%n dienām"], + "_%n day ago_::_%n days ago_" : ["pirms %n dienām","pirms %n dienas","pirms %n dienām"], "last month" : "pagājušajā mēnesī", - "_%n month ago_::_%n months ago_" : ["%n mēneši atpakaļ","%n mēneši atpakaļ","%n mēnešiem"], + "_%n month ago_::_%n months ago_" : ["pirms %n mēnešiem","pirms %n mēneša","pirms %n mēnešiem"], "last year" : "gājušajā gadā", - "_%n year ago_::_%n years ago_" : ["%n gadiem","%n gadiem","%n gadiem"], - "_%n hour ago_::_%n hours ago_" : ["%n stundas atpakaļ","%n stundas atpakaļ","%n stundām"], - "_%n minute ago_::_%n minutes ago_" : ["%n minūtes atpakaļ","%n minūtes atpakaļ","%n minūtēm"], - "seconds ago" : "sekundēm", + "_%n year ago_::_%n years ago_" : ["pirms %n gadiem","pirms %n gada","pirms %n gadiem"], + "_%n hour ago_::_%n hours ago_" : ["pirms %n stundām","pirms %n stundas","pirms %n stundām"], + "_%n minute ago_::_%n minutes ago_" : ["pirms %n minūtēm","pirms %n minūtes","pirms %n minūtēm"], + "seconds ago" : "pirms vairākām sekundēm", "Empty file" : "Tukša datne", "File already exists" : "Datne jau pastāv", "Filename contains at least one invalid character" : "Datnes nosaukums satur vismaz vienu nederīgu rakstzīmi", diff --git a/lib/l10n/lv.json b/lib/l10n/lv.json index f71090c5fd4..865458737df 100644 --- a/lib/l10n/lv.json +++ b/lib/l10n/lv.json @@ -29,14 +29,14 @@ "View profile" : "Skatīt profilu", "today" : "šodien", "yesterday" : "vakar", - "_%n day ago_::_%n days ago_" : ["%n dienas atpakaļ","%n dienas atpakaļ","%n dienām"], + "_%n day ago_::_%n days ago_" : ["pirms %n dienām","pirms %n dienas","pirms %n dienām"], "last month" : "pagājušajā mēnesī", - "_%n month ago_::_%n months ago_" : ["%n mēneši atpakaļ","%n mēneši atpakaļ","%n mēnešiem"], + "_%n month ago_::_%n months ago_" : ["pirms %n mēnešiem","pirms %n mēneša","pirms %n mēnešiem"], "last year" : "gājušajā gadā", - "_%n year ago_::_%n years ago_" : ["%n gadiem","%n gadiem","%n gadiem"], - "_%n hour ago_::_%n hours ago_" : ["%n stundas atpakaļ","%n stundas atpakaļ","%n stundām"], - "_%n minute ago_::_%n minutes ago_" : ["%n minūtes atpakaļ","%n minūtes atpakaļ","%n minūtēm"], - "seconds ago" : "sekundēm", + "_%n year ago_::_%n years ago_" : ["pirms %n gadiem","pirms %n gada","pirms %n gadiem"], + "_%n hour ago_::_%n hours ago_" : ["pirms %n stundām","pirms %n stundas","pirms %n stundām"], + "_%n minute ago_::_%n minutes ago_" : ["pirms %n minūtēm","pirms %n minūtes","pirms %n minūtēm"], + "seconds ago" : "pirms vairākām sekundēm", "Empty file" : "Tukša datne", "File already exists" : "Datne jau pastāv", "Filename contains at least one invalid character" : "Datnes nosaukums satur vismaz vienu nederīgu rakstzīmi", diff --git a/lib/private/AppConfig.php b/lib/private/AppConfig.php index 092d37c3338..a8a6f689ffa 100644 --- a/lib/private/AppConfig.php +++ b/lib/private/AppConfig.php @@ -488,6 +488,14 @@ class AppConfig implements IAppConfig { * @see VALUE_ARRAY */ public function getValueType(string $app, string $key, ?bool $lazy = null): int { + $type = self::VALUE_MIXED; + $ignorable = $lazy ?? false; + $this->matchAndApplyLexiconDefinition($app, $key, $ignorable, $type); + if ($type !== self::VALUE_MIXED) { + // a modified $type means config key is set in Lexicon + return $type; + } + $this->assertParams($app, $key); $this->loadConfig($app, $lazy); diff --git a/lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php b/lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php index 2b3025fccff..b3040673d0f 100644 --- a/lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php +++ b/lib/private/AppFramework/Middleware/PublicShare/PublicShareMiddleware.php @@ -120,7 +120,7 @@ class PublicShareMiddleware extends Middleware { private function throttle($bruteforceProtectionAction, $token): void { $ip = $this->request->getRemoteAddress(); - $this->throttler->sleepDelay($ip, $bruteforceProtectionAction); + $this->throttler->sleepDelayOrThrowOnMax($ip, $bruteforceProtectionAction); $this->throttler->registerAttempt($bruteforceProtectionAction, $ip, ['token' => $token]); } } diff --git a/lib/private/Security/Bruteforce/Throttler.php b/lib/private/Security/Bruteforce/Throttler.php index 21d50848641..065f720ba72 100644 --- a/lib/private/Security/Bruteforce/Throttler.php +++ b/lib/private/Security/Bruteforce/Throttler.php @@ -127,6 +127,13 @@ class Throttler implements IThrottler { */ public function getDelay(string $ip, string $action = ''): int { $attempts = $this->getAttempts($ip, $action); + return $this->calculateDelay($attempts); + } + + /** + * {@inheritDoc} + */ + public function calculateDelay(int $attempts): int { if ($attempts === 0) { return 0; } @@ -199,25 +206,29 @@ class Throttler implements IThrottler { * {@inheritDoc} */ public function sleepDelayOrThrowOnMax(string $ip, string $action = ''): int { - $delay = $this->getDelay($ip, $action); - if (($delay === self::MAX_DELAY_MS) && $this->getAttempts($ip, $action, 0.5) > $this->config->getSystemValueInt('auth.bruteforce.max-attempts', self::MAX_ATTEMPTS)) { - $this->logger->info('IP address blocked because it reached the maximum failed attempts in the last 30 minutes [action: {action}, ip: {ip}]', [ + $attempts = $this->getAttempts($ip, $action, 0.5); + if ($attempts > $this->config->getSystemValueInt('auth.bruteforce.max-attempts', self::MAX_ATTEMPTS)) { + $this->logger->info('IP address blocked because it reached the maximum failed attempts in the last 30 minutes [action: {action}, attempts: {attempts}, ip: {ip}]', [ 'action' => $action, 'ip' => $ip, + 'attempts' => $attempts, ]); // If the ip made too many attempts within the last 30 mins we don't execute anymore throw new MaxDelayReached('Reached maximum delay'); } - if ($delay > 100) { - $this->logger->info('IP address throttled because it reached the attempts limit in the last 30 minutes [action: {action}, delay: {delay}, ip: {ip}]', [ + + $attempts = $this->getAttempts($ip, $action); + if ($attempts > 10) { + $this->logger->info('IP address throttled because it reached the attempts limit in the last 12 hours [action: {action}, attempts: {attempts}, ip: {ip}]', [ 'action' => $action, 'ip' => $ip, - 'delay' => $delay, + 'attempts' => $attempts, ]); } - if (!$this->config->getSystemValueBool('auth.bruteforce.protection.testing')) { - usleep($delay * 1000); + if ($attempts > 0) { + return $this->calculateDelay($attempts); } - return $delay; + + return 0; } } diff --git a/lib/private/Setup.php b/lib/private/Setup.php index 6d3021aff71..959797fb962 100644 --- a/lib/private/Setup.php +++ b/lib/private/Setup.php @@ -14,6 +14,7 @@ use Exception; use InvalidArgumentException; use OC\Authentication\Token\PublicKeyTokenProvider; use OC\Authentication\Token\TokenCleanupJob; +use OC\Core\BackgroundJobs\GenerateMetadataJob; use OC\Log\Rotate; use OC\Preview\BackgroundCleanupJob; use OC\TextProcessing\RemoveOldTasksBackgroundJob; @@ -495,6 +496,7 @@ class Setup { $jobList->add(BackgroundCleanupJob::class); $jobList->add(RemoveOldTasksBackgroundJob::class); $jobList->add(CleanupDeletedUsers::class); + $jobList->add(GenerateMetadataJob::class); } /** diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php index a257bc4f7b5..e1eebe1e450 100644 --- a/lib/private/Share20/DefaultShareProvider.php +++ b/lib/private/Share20/DefaultShareProvider.php @@ -5,6 +5,7 @@ * SPDX-FileCopyrightText: 2016 ownCloud, Inc. * SPDX-License-Identifier: AGPL-3.0-only */ + namespace OC\Share20; use OC\Files\Cache\Cache; @@ -31,6 +32,7 @@ use OCP\Share\IAttributes; use OCP\Share\IManager; use OCP\Share\IShare; use OCP\Share\IShareProviderSupportsAccept; +use OCP\Share\IShareProviderSupportsAllSharesInFolder; use OCP\Share\IShareProviderWithNotification; use Psr\Log\LoggerInterface; use function str_starts_with; @@ -40,7 +42,7 @@ use function str_starts_with; * * @package OC\Share20 */ -class DefaultShareProvider implements IShareProviderWithNotification, IShareProviderSupportsAccept { +class DefaultShareProvider implements IShareProviderWithNotification, IShareProviderSupportsAccept, IShareProviderSupportsAllSharesInFolder { // Special share type for user modified group shares public const SHARE_TYPE_USERGROUP = 2; @@ -603,6 +605,17 @@ class DefaultShareProvider implements IShareProviderWithNotification, IShareProv throw new \Exception('non-shallow getSharesInFolder is no longer supported'); } + return $this->getSharesInFolderInternal($userId, $node, $reshares); + } + + public function getAllSharesInFolder(Folder $node): array { + return $this->getSharesInFolderInternal(null, $node, null); + } + + /** + * @return array<int, list<IShare>> + */ + private function getSharesInFolderInternal(?string $userId, Folder $node, ?bool $reshares): array { $qb = $this->dbConn->getQueryBuilder(); $qb->select('s.*', 'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash', @@ -613,18 +626,20 @@ class DefaultShareProvider implements IShareProviderWithNotification, IShareProv $qb->andWhere($qb->expr()->in('share_type', $qb->createNamedParameter([IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_LINK], IQueryBuilder::PARAM_INT_ARRAY))); - /** - * Reshares for this user are shares where they are the owner. - */ - if ($reshares === false) { - $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))); - } else { - $qb->andWhere( - $qb->expr()->orX( - $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)), - $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)) - ) - ); + if ($userId !== null) { + /** + * Reshares for this user are shares where they are the owner. + */ + if ($reshares !== true) { + $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))); + } else { + $qb->andWhere( + $qb->expr()->orX( + $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)), + $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)) + ) + ); + } } // todo? maybe get these from the oc_mounts table @@ -656,7 +671,6 @@ class DefaultShareProvider implements IShareProviderWithNotification, IShareProv foreach ($chunks as $chunk) { $qb->setParameter('chunk', $chunk, IQueryBuilder::PARAM_INT_ARRAY); - $a = $qb->getSQL(); $cursor = $qb->executeQuery(); while ($data = $cursor->fetch()) { $shares[$data['fileid']][] = $this->createShare($data); diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php index 3b247475afa..2104c07593a 100644 --- a/lib/private/Share20/Manager.php +++ b/lib/private/Share20/Manager.php @@ -51,6 +51,7 @@ use OCP\Share\IProviderFactory; use OCP\Share\IShare; use OCP\Share\IShareProvider; use OCP\Share\IShareProviderSupportsAccept; +use OCP\Share\IShareProviderSupportsAllSharesInFolder; use OCP\Share\IShareProviderWithNotification; use Psr\Log\LoggerInterface; @@ -1213,11 +1214,13 @@ class Manager implements IManager { $shares = []; foreach ($providers as $provider) { if ($isOwnerless) { - foreach ($node->getDirectoryListing() as $childNode) { - $data = $provider->getSharesByPath($childNode); - $fid = $childNode->getId(); - $shares[$fid] ??= []; - $shares[$fid] = array_merge($shares[$fid], $data); + // If the provider does not implement the additional interface, + // we lack a performant way of querying all shares and therefore ignore the provider. + if ($provider instanceof IShareProviderSupportsAllSharesInFolder) { + foreach ($provider->getAllSharesInFolder($node) as $fid => $data) { + $shares[$fid] ??= []; + $shares[$fid] = array_merge($shares[$fid], $data); + } } } else { foreach ($provider->getSharesInFolder($userId, $node, $reshares) as $fid => $data) { diff --git a/lib/public/Share/IShareProviderSupportsAllSharesInFolder.php b/lib/public/Share/IShareProviderSupportsAllSharesInFolder.php new file mode 100644 index 00000000000..e27da7682ce --- /dev/null +++ b/lib/public/Share/IShareProviderSupportsAllSharesInFolder.php @@ -0,0 +1,24 @@ +<?php + +/** + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCP\Share; + +use OCP\Files\Folder; + +/** + * Allows defining a IShareProvider with support for the getAllSharesInFolder method. + * + * @since 32.0.0 + */ +interface IShareProviderSupportsAllSharesInFolder extends IShareProvider { + /** + * Get all shares in a folder. + * + * @return array<int, list<IShare>> + * @since 32.0.0 + */ + public function getAllSharesInFolder(Folder $node): array; +} |