Compare commits

..

4 Commits

Author SHA1 Message Date
Côme Chilliet b9c6206c2f chore: Small fixups and fixme comments
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
2026-03-12 12:11:40 +01:00
Carl Schwan c7fca0071b fixup! refactor: Move base.php to a proper class 2026-03-12 09:30:55 +01:00
Carl Schwan dbc41af77f fixup! refactor: Move base.php to a proper class 2026-03-11 16:36:34 +01:00
Carl Schwan db558a7394 refactor: Move base.php to a proper class
Signed-off-by: Carl Schwan <carlschwan@kde.org>
2026-03-10 09:17:04 +01:00
309 changed files with 4713 additions and 3144 deletions
-29
View File
@@ -4,7 +4,6 @@
# Global exclude
.editorconfig
.envrc
.git
.git-blame-ignore-revs
.gitattributes
@@ -12,40 +11,12 @@
.gitignore
.gitmodules
.idea
.jshint
.l10nignore
.mailmap
.nextcloudignore
.noopenapi
.npmignore
.php-cs-fixer*
.pre-commit-config.yaml
.tag
.tx
CHANGELOG.md
CODE_OF_CONDUCT.md
COPYING-README
DESIGN.md
Makefile
README.md
SECURITY.md
codecov.yml
cs-fixer
csfixer
cypress
eslint.config.js
flake.lock
flake.nix
openapi-extractor
phpunit
psalm
psalm*.xml
rector
stylelint.config.js
tests
tsconfig.json
vitest.config.ts
window.d.ts
# Server specific
/.devcontainer
+1 -1
View File
@@ -23,7 +23,7 @@ OC.L10N.register(
"Could not reload comments" : "Kon reactie niet opnieuw laden",
"Failed to mark comments as read" : "Kon reacties niet als gelezen markeren",
"Unable to load the comments list" : "Kan reactielijst niet laden",
"No comments yet, start the conversation!" : "Nog geen reacties, start het gesprek!",
"No comments yet, start the conversation!" : "Nog geen reacties, start de discussie!",
"No more messages" : "Geen berichten meer",
"Retry" : "Opnieuw proberen",
"_1 new comment_::_{unread} new comments_" : ["1 nieuwe reactie","{unread} nieuwe reacties"],
+1 -1
View File
@@ -21,7 +21,7 @@
"Could not reload comments" : "Kon reactie niet opnieuw laden",
"Failed to mark comments as read" : "Kon reacties niet als gelezen markeren",
"Unable to load the comments list" : "Kan reactielijst niet laden",
"No comments yet, start the conversation!" : "Nog geen reacties, start het gesprek!",
"No comments yet, start the conversation!" : "Nog geen reacties, start de discussie!",
"No more messages" : "Geen berichten meer",
"Retry" : "Opnieuw proberen",
"_1 new comment_::_{unread} new comments_" : ["1 nieuwe reactie","{unread} nieuwe reacties"],
+1 -1
View File
@@ -10,7 +10,7 @@
<name>WebDAV</name>
<summary>WebDAV endpoint</summary>
<description>WebDAV endpoint</description>
<version>1.38.0</version>
<version>1.37.0</version>
<licence>agpl</licence>
<author>owncloud.org</author>
<namespace>DAV</namespace>
+2 -1
View File
@@ -92,6 +92,7 @@ $server = $serverFactory->createServer(
}
$share = $authBackend->getShare();
$owner = $share->getShareOwner();
$isReadable = $share->getPermissions() & Constants::PERMISSION_READ;
$fileId = $share->getNodeId();
@@ -106,7 +107,7 @@ $server = $serverFactory->createServer(
Filesystem::logWarningWhenAddingStorageWrapper($previousLog);
$rootFolder = Server::get(IRootFolder::class);
$userFolder = $rootFolder->getUserFolder($share->getSharedBy());
$userFolder = $rootFolder->getUserFolder($owner);
$node = $userFolder->getFirstNodeById($fileId);
if (!$node) {
throw new \Sabre\DAV\Exception\NotFound();
+2 -1
View File
@@ -99,6 +99,7 @@ $server = $serverFactory->createServer(true, $baseuri, $requestUri, $authPlugin,
}
$share = $authBackend->getShare();
$owner = $share->getShareOwner();
$isReadable = $share->getPermissions() & Constants::PERMISSION_READ;
$fileId = $share->getNodeId();
@@ -134,7 +135,7 @@ $server = $serverFactory->createServer(true, $baseuri, $requestUri, $authPlugin,
Filesystem::logWarningWhenAddingStorageWrapper($previousLog);
$rootFolder = Server::get(IRootFolder::class);
$userFolder = $rootFolder->getUserFolder($share->getSharedBy());
$userFolder = $rootFolder->getUserFolder($owner);
$node = $userFolder->getFirstNodeById($fileId);
if (!$node) {
throw new NotFound();
@@ -389,7 +389,6 @@ return array(
'OCA\\DAV\\Migration\\Version1034Date20250605132605' => $baseDir . '/../lib/Migration/Version1034Date20250605132605.php',
'OCA\\DAV\\Migration\\Version1034Date20250813093701' => $baseDir . '/../lib/Migration/Version1034Date20250813093701.php',
'OCA\\DAV\\Migration\\Version1036Date20251202000000' => $baseDir . '/../lib/Migration/Version1036Date20251202000000.php',
'OCA\\DAV\\Migration\\Version1038Date20260302000000' => $baseDir . '/../lib/Migration/Version1038Date20260302000000.php',
'OCA\\DAV\\Model\\ExampleEvent' => $baseDir . '/../lib/Model/ExampleEvent.php',
'OCA\\DAV\\Paginate\\LimitedCopyIterator' => $baseDir . '/../lib/Paginate/LimitedCopyIterator.php',
'OCA\\DAV\\Paginate\\PaginateCache' => $baseDir . '/../lib/Paginate/PaginateCache.php',
@@ -404,7 +404,6 @@ class ComposerStaticInitDAV
'OCA\\DAV\\Migration\\Version1034Date20250605132605' => __DIR__ . '/..' . '/../lib/Migration/Version1034Date20250605132605.php',
'OCA\\DAV\\Migration\\Version1034Date20250813093701' => __DIR__ . '/..' . '/../lib/Migration/Version1034Date20250813093701.php',
'OCA\\DAV\\Migration\\Version1036Date20251202000000' => __DIR__ . '/..' . '/../lib/Migration/Version1036Date20251202000000.php',
'OCA\\DAV\\Migration\\Version1038Date20260302000000' => __DIR__ . '/..' . '/../lib/Migration/Version1038Date20260302000000.php',
'OCA\\DAV\\Model\\ExampleEvent' => __DIR__ . '/..' . '/../lib/Model/ExampleEvent.php',
'OCA\\DAV\\Paginate\\LimitedCopyIterator' => __DIR__ . '/..' . '/../lib/Paginate/LimitedCopyIterator.php',
'OCA\\DAV\\Paginate\\PaginateCache' => __DIR__ . '/..' . '/../lib/Paginate/PaginateCache.php',
-1
View File
@@ -236,7 +236,6 @@ OC.L10N.register(
"Failed to check file size: %1$s" : "Produciuse un erro ao comprobar o tamaño do ficheiro: %1$s",
"Could not open file: %1$s (%2$d), file does seem to exist" : "Non foi posíbel abrir o ficheiro: %1$s (%2$d), semella o ficheiro existe",
"Could not open file: %1$s (%2$d), file doesn't seem to exist" : "Non foi posíbel abrir o ficheiro: %1$s (%2$d), semella o ficheiro non existe",
"Failed to get size for : %1$s" : "Produciuse un fallo ao obter o tamaño de: %1$s",
"Encryption not ready: %1$s" : "A cifraxe non está preparada: %1$s",
"Failed to open file: %1$s" : "Produciuse un erro ao abrir o ficheiro: %1$s",
"Failed to unlink: %1$s" : "Produciuse un erro ao desligar: %1$s",
-1
View File
@@ -234,7 +234,6 @@
"Failed to check file size: %1$s" : "Produciuse un erro ao comprobar o tamaño do ficheiro: %1$s",
"Could not open file: %1$s (%2$d), file does seem to exist" : "Non foi posíbel abrir o ficheiro: %1$s (%2$d), semella o ficheiro existe",
"Could not open file: %1$s (%2$d), file doesn't seem to exist" : "Non foi posíbel abrir o ficheiro: %1$s (%2$d), semella o ficheiro non existe",
"Failed to get size for : %1$s" : "Produciuse un fallo ao obter o tamaño de: %1$s",
"Encryption not ready: %1$s" : "A cifraxe non está preparada: %1$s",
"Failed to open file: %1$s" : "Produciuse un erro ao abrir o ficheiro: %1$s",
"Failed to unlink: %1$s" : "Produciuse un erro ao desligar: %1$s",
-1
View File
@@ -236,7 +236,6 @@ OC.L10N.register(
"Failed to check file size: %1$s" : "Kon bestandsomvang niet controleren: %1$s",
"Could not open file: %1$s (%2$d), file does seem to exist" : "Kon bestand niet openen: %1$s (%2$d), bestand lijkt wel te bestaan",
"Could not open file: %1$s (%2$d), file doesn't seem to exist" : "Kon bestand niet openen: %1$s (%2$d), bestand lijkt niet te bestaan",
"Failed to get size for : %1$s" : "Niet gelukt om grootte te krijgen voor : %1$s",
"Encryption not ready: %1$s" : "Versleuteling niet gereed: %1$s",
"Failed to open file: %1$s" : "Kon het bestand %1$s niet openen",
"Failed to unlink: %1$s" : "Kon link niet verwijderen: %1$s",
-1
View File
@@ -234,7 +234,6 @@
"Failed to check file size: %1$s" : "Kon bestandsomvang niet controleren: %1$s",
"Could not open file: %1$s (%2$d), file does seem to exist" : "Kon bestand niet openen: %1$s (%2$d), bestand lijkt wel te bestaan",
"Could not open file: %1$s (%2$d), file doesn't seem to exist" : "Kon bestand niet openen: %1$s (%2$d), bestand lijkt niet te bestaan",
"Failed to get size for : %1$s" : "Niet gelukt om grootte te krijgen voor : %1$s",
"Encryption not ready: %1$s" : "Versleuteling niet gereed: %1$s",
"Failed to open file: %1$s" : "Kon het bestand %1$s niet openen",
"Failed to unlink: %1$s" : "Kon link niet verwijderen: %1$s",
-1
View File
@@ -151,7 +151,6 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
'{http://apple.com/ns/ical/}calendar-order' => ['calendarorder', 'int'],
'{http://apple.com/ns/ical/}calendar-color' => ['calendarcolor', 'string'],
'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}deleted-at' => ['deleted_at', 'int'],
'{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}default-alarm' => ['default_alarm', 'int'],
];
/**
+1 -2
View File
@@ -22,7 +22,6 @@ use OCP\IDBConnection;
use OCP\IGroupManager;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\L10N\IFactory;
use OCP\Security\ISecureRandom;
use OCP\Server;
use Psr\Log\LoggerInterface;
@@ -67,7 +66,7 @@ class CreateCalendar extends Command {
Server::get(ProxyMapper::class),
Server::get(KnownUserService::class),
Server::get(IConfig::class),
Server::get(IFactory::class),
\OC::$server->getL10NFactory(),
);
$random = Server::get(ISecureRandom::class);
$logger = Server::get(LoggerInterface::class);
+1 -2
View File
@@ -8,7 +8,6 @@
namespace OCA\DAV\Files;
use OCP\Files\FileInfo;
use OCP\Files\IRootFolder;
use OCP\IUserSession;
use OCP\Server;
use Sabre\DAV\INode;
@@ -36,7 +35,7 @@ class RootCollection extends AbstractPrincipalCollection {
// in the future this could be considered to be used for accessing shared files
return new SimpleCollection($name);
}
$userFolder = Server::get(IRootFolder::class)->getUserFolder($user->getUID());
$userFolder = \OC::$server->getUserFolder();
if (!($userFolder instanceof FileInfo)) {
throw new \Exception('Home does not exist');
}
@@ -43,7 +43,7 @@ class PublicLinkCheckPlugin extends ServerPlugin {
}
public function beforeMethod(RequestInterface $request, ResponseInterface $response) {
// verify that the initiator didn't have their share permissions revoked
// verify that the owner didn't have their share permissions revoked
if ($this->fileInfo && !$this->fileInfo->isShareable()) {
throw new NotFound();
}
@@ -1,37 +0,0 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\DAV\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\Attributes\AddColumn;
use OCP\Migration\Attributes\ColumnType;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
#[AddColumn(table: 'calendars', name: 'default_alarm', type: ColumnType::STRING)]
class Version1038Date20260302000000 extends SimpleMigrationStep {
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$calendarsTable = $schema->getTable('calendars');
if (!$calendarsTable->hasColumn('default_alarm')) {
$calendarsTable->addColumn('default_alarm', Types::INTEGER, [
'notnull' => false,
'default' => null,
]);
}
return $schema;
}
}
+1 -2
View File
@@ -42,7 +42,6 @@ use OCP\IDBConnection;
use OCP\IGroupManager;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\L10N\IFactory;
use OCP\Security\ISecureRandom;
use OCP\Server;
use OCP\SystemTag\ISystemTagManager;
@@ -76,7 +75,7 @@ class RootCollection extends SimpleCollection {
$proxyMapper,
Server::get(KnownUserService::class),
Server::get(IConfig::class),
Server::get(IFactory::class)
\OC::$server->getL10NFactory()
);
$groupPrincipalBackend = new GroupPrincipalBackend($groupManager, $userSession, $shareManager, $config);
@@ -15,7 +15,6 @@ use OCP\AppFramework\Services\IAppConfig;
use OCP\Files\AppData\IAppDataFactory;
use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
use OCP\IL10N;
use Psr\Log\LoggerInterface;
use Symfony\Component\Uid\Uuid;
@@ -27,7 +26,6 @@ class ExampleContactService {
private readonly IAppConfig $appConfig,
private readonly LoggerInterface $logger,
private readonly CardDavBackend $cardDav,
private readonly IL10N $l,
) {
$this->appData = $appDataFactory->get(Application::APP_ID);
}
@@ -133,9 +131,6 @@ class ExampleContactService {
} else {
$vcard->add('REV', $newRev);
}
if (!$vcard->Note) {
$vcard->add('note', $this->l->t('This is an example contact'));
}
// Level 3 means that the document is invalid
// https://sabre.io/vobject/vcard/#validating-vcard
@@ -1881,43 +1881,4 @@ EOD;
);
}
public function testDefaultAlarmProperty(): void {
$calendarId = $this->createTestCalendar();
// Test setting default alarm property to 15 minutes before (-900 seconds)
$patch = new PropPatch([
'{http://nextcloud.com/ns}default-alarm' => -900
]);
$this->backend->updateCalendar($calendarId, $patch);
$patch->commit();
// Verify the property was set
$calendars = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
$this->assertCount(1, $calendars);
$this->assertEquals(-900, $calendars[0]['{http://nextcloud.com/ns}default-alarm']);
// Test updating to a different value (1 day before = -86400 seconds)
$patch = new PropPatch([
'{http://nextcloud.com/ns}default-alarm' => -86400
]);
$this->backend->updateCalendar($calendarId, $patch);
$patch->commit();
$calendars = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
$this->assertEquals(-86400, $calendars[0]['{http://nextcloud.com/ns}default-alarm']);
// Test setting to "none"
$patch = new PropPatch([
'{http://nextcloud.com/ns}default-alarm' => null
]);
$this->backend->updateCalendar($calendarId, $patch);
$patch->commit();
$calendars = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER);
$this->assertEquals(null, $calendars[0]['{http://nextcloud.com/ns}default-alarm']);
// Clean up
$this->backend->deleteCalendar($calendars[0]['id'], true);
}
}
@@ -18,7 +18,6 @@ use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
use OCP\Files\SimpleFS\ISimpleFile;
use OCP\Files\SimpleFS\ISimpleFolder;
use OCP\IL10N;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
use Symfony\Component\Uid\Uuid;
@@ -32,7 +31,6 @@ class ExampleContactServiceTest extends TestCase {
protected LoggerInterface&MockObject $logger;
protected IAppConfig&MockObject $appConfig;
protected IAppData&MockObject $appData;
protected IL10N&MockObject $l;
protected function setUp(): void {
parent::setUp();
@@ -41,7 +39,6 @@ class ExampleContactServiceTest extends TestCase {
$this->appDataFactory = $this->createMock(IAppDataFactory::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->appConfig = $this->createMock(IAppConfig::class);
$this->l = $this->createMock((IL10N::class));
$this->appData = $this->createMock(IAppData::class);
$this->appDataFactory->method('get')
@@ -53,7 +50,6 @@ class ExampleContactServiceTest extends TestCase {
$this->appConfig,
$this->logger,
$this->cardDav,
$this->l,
);
}
-4
View File
@@ -22,20 +22,16 @@ OC.L10N.register(
"Sharing" : "Delen",
"Federated file sharing" : "Gefedereerd delen",
"Provide federated file sharing across servers" : "Voorzien in gefedereerd delen van bestanden over verschillende servers",
"Enable data upload" : "Schakel data upload in",
"Disable upload" : "Schakel upload uit",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Dit wordt gebruikt om de federatieve cloud-ID op te halen om federatief delen gemakkelijker te maken.",
"Share with me through my #Nextcloud Federated Cloud ID, see {url}" : "Deel met mij via mijn #Nextcloud Federated Cloud-ID, zie {url}",
"Share with me through my #Nextcloud Federated Cloud ID" : "Deel met mij via mijn #Nextcloud gefedereerde Cloud-ID",
"Share with me via Nextcloud" : "Deel met mij via Nextcloud",
"Cloud ID copied" : "Cloud ID gekopieerd",
"Copy" : "Kopiëren",
"Clipboard not available. Please copy the cloud ID manually." : "Klembord niet beschikbaar. Kopieer de cloud-ID handmatig.",
"Copied!" : "Gekopieerd!",
"Federated Cloud" : "Gefedereerde Cloud",
"Your Federated Cloud ID" : "Jouw Federated Cloud-ID",
"Share it so your friends can share files with you:" : "Deel het, zodat anderen bestanden met jou kunnen delen:",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Toevoegen aan je website",
-4
View File
@@ -20,20 +20,16 @@
"Sharing" : "Delen",
"Federated file sharing" : "Gefedereerd delen",
"Provide federated file sharing across servers" : "Voorzien in gefedereerd delen van bestanden over verschillende servers",
"Enable data upload" : "Schakel data upload in",
"Disable upload" : "Schakel upload uit",
"This is used to retrieve the federated cloud ID to make federated sharing easier." : "Dit wordt gebruikt om de federatieve cloud-ID op te halen om federatief delen gemakkelijker te maken.",
"Share with me through my #Nextcloud Federated Cloud ID, see {url}" : "Deel met mij via mijn #Nextcloud Federated Cloud-ID, zie {url}",
"Share with me through my #Nextcloud Federated Cloud ID" : "Deel met mij via mijn #Nextcloud gefedereerde Cloud-ID",
"Share with me via Nextcloud" : "Deel met mij via Nextcloud",
"Cloud ID copied" : "Cloud ID gekopieerd",
"Copy" : "Kopiëren",
"Clipboard not available. Please copy the cloud ID manually." : "Klembord niet beschikbaar. Kopieer de cloud-ID handmatig.",
"Copied!" : "Gekopieerd!",
"Federated Cloud" : "Gefedereerde Cloud",
"Your Federated Cloud ID" : "Jouw Federated Cloud-ID",
"Share it so your friends can share files with you:" : "Deel het, zodat anderen bestanden met jou kunnen delen:",
"Bluesky" : "Bluesky",
"Facebook" : "Facebook",
"Mastodon" : "Mastodon",
"Add to your website" : "Toevoegen aan je website",
@@ -128,30 +128,30 @@ class FederatedShareProvider implements IShareProvider, IShareProviderSupportsAl
$share->setSharedWith($cloudId->getId());
try {
$remoteShare = $this->getShareFromExternalShareTable($share->getShareOwner(), $share->getTarget());
$remoteShare = $this->getShareFromExternalShareTable($share);
} catch (ShareNotFound $e) {
$remoteShare = null;
}
if ($remoteShare) {
$ownerCloudId = $this->cloudIdManager->getCloudId($remoteShare['owner'], $remoteShare['remote']);
$shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $ownerCloudId->getId(), $permissions, 'tmp_token_' . time(), $shareType, $expirationDate);
[$token, $remoteId] = $this->notifications->requestReShare(
$remoteShare['share_token'],
$remoteShare['remote_id'],
$shareId,
$remoteShare['remote'],
$shareWith,
$permissions,
$share->getNode()->getName(),
$shareType,
);
// remote share was create successfully if we get a valid token as return
if (is_string($token) && $token !== '') {
try {
$ownerCloudId = $this->cloudIdManager->getCloudId($remoteShare['owner'], $remoteShare['remote']);
$shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $ownerCloudId->getId(), $permissions, 'tmp_token_' . time(), $shareType, $expirationDate);
$share->setId($shareId);
[$token, $remoteId] = $this->askOwnerToReShare($shareWith, $share, $shareId);
// remote share was create successfully if we get a valid token as return
$send = is_string($token) && $token !== '';
} catch (\Exception $e) {
// fall back to old re-share behavior if the remote server
// doesn't support flat re-shares (was introduced with Nextcloud 9.1)
$this->removeShareFromTable($share);
$shareId = $this->createFederatedShare($share);
}
if ($send) {
$this->updateSuccessfulReshare($shareId, $token);
$this->storeRemoteId($shareId, $remoteId);
} else {
$this->removeShareFromTable($shareId);
$this->removeShareFromTable($share);
$message_t = $this->l->t('File is already shared with %s', [$shareWith]);
throw new \Exception($message_t);
}
@@ -216,7 +216,7 @@ class FederatedShareProvider implements IShareProvider, IShareProviderSupportsAl
}
if ($failure) {
$this->removeShareFromTable($shareId);
$this->removeShareFromTableById($shareId);
$message_t = $this->l->t('Sharing %1$s failed, could not find %2$s, maybe the server is currently unreachable or uses a self-signed certificate.',
[$share->getNode()->getName(), $share->getSharedWith()]);
throw new \Exception($message_t);
@@ -225,17 +225,45 @@ class FederatedShareProvider implements IShareProvider, IShareProviderSupportsAl
return $shareId;
}
/**
* @param string $shareWith
* @param IShare $share
* @param string $shareId internal share Id
* @return array
* @throws \Exception
*/
protected function askOwnerToReShare($shareWith, IShare $share, $shareId) {
$remoteShare = $this->getShareFromExternalShareTable($share);
$token = $remoteShare['share_token'];
$remoteId = $remoteShare['remote_id'];
$remote = $remoteShare['remote'];
[$token, $remoteId] = $this->notifications->requestReShare(
$token,
$remoteId,
$shareId,
$remote,
$shareWith,
$share->getPermissions(),
$share->getNode()->getName(),
$share->getShareType(),
);
return [$token, $remoteId];
}
/**
* get federated share from the share_external table but exclude mounted link shares
*
* @param IShare $share
* @return array
* @throws ShareNotFound
*/
protected function getShareFromExternalShareTable(string $owner, string $target) {
protected function getShareFromExternalShareTable(IShare $share) {
$query = $this->dbConnection->getQueryBuilder();
$query->select('*')->from($this->externalShareTable)
->where($query->expr()->eq('user', $query->createNamedParameter($owner)))
->andWhere($query->expr()->eq('mountpoint', $query->createNamedParameter($target)));
->where($query->expr()->eq('user', $query->createNamedParameter($share->getShareOwner())))
->andWhere($query->expr()->eq('mountpoint', $query->createNamedParameter($share->getTarget())));
$qResult = $query->executeQuery();
$result = $qResult->fetchAllAssociative();
$qResult->closeCursor();
@@ -440,7 +468,7 @@ class FederatedShareProvider implements IShareProvider, IShareProviderSupportsAl
// only remove the share when all messages are send to not lose information
// about the share to early
$this->removeShareFromTable($share->getId());
$this->removeShareFromTable($share);
}
/**
@@ -465,10 +493,19 @@ class FederatedShareProvider implements IShareProvider, IShareProviderSupportsAl
}
}
/**
* remove share from table
*
* @param IShare $share
*/
public function removeShareFromTable(IShare $share) {
$this->removeShareFromTableById($share->getId());
}
/**
* Remove share from table.
*/
public function removeShareFromTable(string $shareId): void {
private function removeShareFromTableById(string $shareId): void {
$qb = $this->dbConnection->getQueryBuilder();
$qb->delete('share')
->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)))
@@ -382,7 +382,7 @@ class CloudFederationProviderFiles implements ISignedCloudFederationProvider {
* @throws ShareNotFound
*/
protected function executeDeclineShare(IShare $share): void {
$this->federatedShareProvider->removeShareFromTable($share->getId());
$this->federatedShareProvider->removeShareFromTable($share);
$user = $this->getCorrectUser($share);
@@ -420,7 +420,7 @@ class CloudFederationProviderFiles implements ISignedCloudFederationProvider {
$share = $this->federatedShareProvider->getShareById($id);
$this->verifyShare($share, $token);
$this->federatedShareProvider->removeShareFromTable($share->getId());
$this->federatedShareProvider->removeShareFromTable($share);
return [];
}
@@ -249,18 +249,18 @@ class FederatedShareProviderReshareRemoteTest extends \Test\TestCase {
$qb6->method('executeQuery')->willReturn($result6);
$queryBuilderMatcher = $this->exactly(7);
$queryBuilderMatcher = $this->exactly(8);
$this->connection
->expects($queryBuilderMatcher)
->method('getQueryBuilder')
->willReturnCallback(function () use ($queryBuilderMatcher, $qb1, $qb2, $qb3, $qb4, $qb5, $qb6) {
return match ($queryBuilderMatcher->numberOfInvocations()) {
1, 2 => $qb1,
3 => $qb2,
3, 5 => $qb2,
4 => $qb3,
5 => $qb4,
6 => $qb5,
7 => $qb6,
6 => $qb4,
7 => $qb5,
8 => $qb6,
default => throw new LogicException('Unexpected number of invocations for getQueryBuilder')
};
});
@@ -133,8 +133,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
->setPermissions(19)
->setShareType(IShare::TYPE_REMOTE)
->setExpirationDate($expirationDate)
->setNode($node)
->setTarget('');
->setNode($node);
$this->tokenHandler->method('generateToken')->willReturn('token');
@@ -216,8 +215,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
->setShareOwner('shareOwner')
->setPermissions(19)
->setShareType(IShare::TYPE_REMOTE)
->setNode($node)
->setTarget('');
->setNode($node);
$this->tokenHandler->method('generateToken')->willReturn('token');
@@ -270,8 +268,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
->setShareOwner('shareOwner')
->setPermissions(19)
->setShareType(IShare::TYPE_REMOTE)
->setNode($node)
->setTarget('');
->setNode($node);
$this->tokenHandler->method('generateToken')->willReturn('token');
@@ -362,8 +359,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
->setShareOwner('shareOwner')
->setPermissions(19)
->setShareType(IShare::TYPE_REMOTE)
->setNode($node)
->setTarget('');
->setNode($node);
$this->tokenHandler->method('generateToken')->willReturn('token');
@@ -435,8 +431,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
->setPermissions(19)
->setShareType(IShare::TYPE_REMOTE)
->setExpirationDate(new \DateTime('2019-02-01T01:02:03'))
->setNode($node)
->setTarget('');
->setNode($node);
$this->tokenHandler->method('generateToken')->willReturn('token');
$this->addressHandler->expects($this->any())->method('generateRemoteURL')
@@ -509,8 +504,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
->setShareOwner('shareOwner')
->setPermissions(19)
->setShareType(IShare::TYPE_REMOTE)
->setNode($node)
->setTarget('');
->setNode($node);
$this->provider->create($share);
$share2 = $this->shareManager->newShare();
@@ -519,8 +513,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
->setShareOwner('shareOwner')
->setPermissions(19)
->setShareType(IShare::TYPE_REMOTE)
->setNode($node)
->setTarget('');
->setNode($node);
$this->provider->create($share2);
$shares = $this->provider->getSharesBy('sharedBy', IShare::TYPE_REMOTE, null, false, -1, 0);
@@ -555,8 +548,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
->setShareOwner('shareOwner')
->setPermissions(19)
->setShareType(IShare::TYPE_REMOTE)
->setNode($node)
->setTarget('');
->setNode($node);
$this->provider->create($share);
$node2 = $this->getMockBuilder(File::class)->getMock();
@@ -569,8 +561,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
->setShareOwner('shareOwner')
->setPermissions(19)
->setShareType(IShare::TYPE_REMOTE)
->setNode($node2)
->setTarget('');
->setNode($node2);
$this->provider->create($share2);
$shares = $this->provider->getSharesBy('sharedBy', IShare::TYPE_REMOTE, $node2, false, -1, 0);
@@ -604,8 +595,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
->setShareOwner('shareOwner')
->setPermissions(19)
->setShareType(IShare::TYPE_REMOTE)
->setNode($node)
->setTarget('');
->setNode($node);
$this->provider->create($share);
$share2 = $this->shareManager->newShare();
@@ -614,8 +604,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
->setShareOwner('shareOwner')
->setPermissions(19)
->setShareType(IShare::TYPE_REMOTE)
->setNode($node)
->setTarget('');
->setNode($node);
$this->provider->create($share2);
$shares = $this->provider->getSharesBy('shareOwner', IShare::TYPE_REMOTE, null, true, -1, 0);
@@ -656,8 +645,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
->setShareOwner('shareOwner')
->setPermissions(19)
->setShareType(IShare::TYPE_REMOTE)
->setNode($node)
->setTarget('');
->setNode($node);
$this->provider->create($share);
$share2 = $this->shareManager->newShare();
@@ -666,8 +654,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
->setShareOwner('shareOwner')
->setPermissions(19)
->setShareType(IShare::TYPE_REMOTE)
->setNode($node)
->setTarget('');
->setNode($node);
$this->provider->create($share2);
$shares = $this->provider->getSharesBy('shareOwner', IShare::TYPE_REMOTE, null, true, 1, 1);
@@ -848,8 +835,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
->setShareOwner($u1->getUID())
->setPermissions(Constants::PERMISSION_READ)
->setShareType(IShare::TYPE_REMOTE)
->setNode($file1)
->setTarget('');
->setNode($file1);
$this->provider->create($share1);
$share2 = $this->shareManager->newShare();
@@ -858,8 +844,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
->setShareOwner($u1->getUID())
->setPermissions(Constants::PERMISSION_READ)
->setShareType(IShare::TYPE_REMOTE)
->setNode($file2)
->setTarget('');
->setNode($file2);
$this->provider->create($share2);
$result = $this->provider->getSharesInFolder($u1->getUID(), $folder1, false);
@@ -910,8 +895,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
->setShareOwner($u1->getUID())
->setPermissions(Constants::PERMISSION_READ)
->setShareType(IShare::TYPE_REMOTE)
->setNode($file1)
->setTarget('');
->setNode($file1);
$this->provider->create($share1);
$share2 = $this->shareManager->newShare();
@@ -920,8 +904,7 @@ class FederatedShareProviderTest extends \Test\TestCase {
->setShareOwner($u1->getUID())
->setPermissions(Constants::PERMISSION_READ)
->setShareType(IShare::TYPE_REMOTE)
->setNode($file1)
->setTarget('');
->setNode($file1);
$this->provider->create($share2);
$result = $this->provider->getAccessList([$file1], true);
-4
View File
@@ -122,7 +122,6 @@ OC.L10N.register(
"General" : "Yleiset",
"Sort favorites first" : "Järjestä suosikit ensiksi",
"Sort folders before files" : "Järjestä kansiot ennen tiedostoja",
"Enable folder tree view" : "Käytä kansiopuunäkymää",
"Default view" : "Oletusnäkymä",
"All files" : "Kaikki tiedostot",
"Personal files" : "Henkilökohtaiset tiedostot",
@@ -132,8 +131,6 @@ OC.L10N.register(
"Selection" : "Valinta",
"Select all files" : "Valitse kaikki tiedostot",
"Deselect all" : "Poista valinnat",
"Select or deselect" : "Valitse tai poista valinta",
"Select a range" : "Valitse väliltä",
"Navigation" : "Navigointi",
"Go to parent folder" : "Siirry ylätason kansioon",
"Go to file above" : "Siirry yllä olevaan tiedostoon",
@@ -142,7 +139,6 @@ OC.L10N.register(
"Go right in grid" : "Siirry oikealle ruudukossa",
"View" : "Näytä",
"Toggle grid view" : "Ruudukkonäkymä päälle/pois",
"Show those shortcuts" : "Näytä pikanäppäimet",
"Warnings" : "Varoitukset",
"Warn before changing a file extension" : "Varoita ennen tiedostopäätteen muuttamista",
"Warn before deleting a file" : "Varoita ennen tiedoston poistamista",
-4
View File
@@ -120,7 +120,6 @@
"General" : "Yleiset",
"Sort favorites first" : "Järjestä suosikit ensiksi",
"Sort folders before files" : "Järjestä kansiot ennen tiedostoja",
"Enable folder tree view" : "Käytä kansiopuunäkymää",
"Default view" : "Oletusnäkymä",
"All files" : "Kaikki tiedostot",
"Personal files" : "Henkilökohtaiset tiedostot",
@@ -130,8 +129,6 @@
"Selection" : "Valinta",
"Select all files" : "Valitse kaikki tiedostot",
"Deselect all" : "Poista valinnat",
"Select or deselect" : "Valitse tai poista valinta",
"Select a range" : "Valitse väliltä",
"Navigation" : "Navigointi",
"Go to parent folder" : "Siirry ylätason kansioon",
"Go to file above" : "Siirry yllä olevaan tiedostoon",
@@ -140,7 +137,6 @@
"Go right in grid" : "Siirry oikealle ruudukossa",
"View" : "Näytä",
"Toggle grid view" : "Ruudukkonäkymä päälle/pois",
"Show those shortcuts" : "Näytä pikanäppäimet",
"Warnings" : "Varoitukset",
"Warn before changing a file extension" : "Varoita ennen tiedostopäätteen muuttamista",
"Warn before deleting a file" : "Varoita ennen tiedoston poistamista",
-1
View File
@@ -95,7 +95,6 @@ OC.L10N.register(
"Another entry with the same name already exists." : "Xa existe outra entrada co mesmo nome.",
"Invalid filename." : "Nome de ficheiro incorrecto.",
"Rename file" : "Cambiar o nome do ficheiro",
"Recently created" : "Creado recentemente",
"Folder" : "Cartafol",
"Unknown file type" : "Tipo de ficheiro descoñecido",
"{ext} image" : "Imaxe {ext}",
-1
View File
@@ -93,7 +93,6 @@
"Another entry with the same name already exists." : "Xa existe outra entrada co mesmo nome.",
"Invalid filename." : "Nome de ficheiro incorrecto.",
"Rename file" : "Cambiar o nome do ficheiro",
"Recently created" : "Creado recentemente",
"Folder" : "Cartafol",
"Unknown file type" : "Tipo de ficheiro descoñecido",
"{ext} image" : "Imaxe {ext}",
-19
View File
@@ -79,7 +79,6 @@ OC.L10N.register(
"Go to the \"{dir}\" directory" : "Ga naar de \"{dir}\" map",
"Current directory path" : "Huidig directory pad",
"Share" : "Delen",
"Reload content" : "Laad inhoud opnieuw",
"Your have used your space quota and cannot upload files anymore" : "Je hebt je ruimtequotum gebruikt en kan geen bestanden meer uploaden",
"You do not have permission to upload or create files here." : "Je hebt geen toestemming om hier bestanden te uploaden of aan te maken.",
"Drag and drop files here to upload" : "Drag en drop bestanden hier om te uploaden",
@@ -95,7 +94,6 @@ OC.L10N.register(
"Another entry with the same name already exists." : "Er bestaat al een ander item met dezelfde naam",
"Invalid filename." : "Ongeldige bestandsnaam",
"Rename file" : "Bestand hernoemen",
"Recently created" : "Recentelijk gemaakt",
"Folder" : "Map",
"Unknown file type" : "Onbekend bestandstype",
"{ext} image" : "{ext} afbeelding",
@@ -111,7 +109,6 @@ OC.L10N.register(
"Last 30 days" : "Laatste 30 dagen",
"This year ({year})" : "Dit jaar ({year})",
"Last year ({year})" : "Afgelopen jaar ({year})",
"Custom range" : "Aangepast bereik",
"Custom date range" : "Aangepast datumbereik",
"Search everywhere" : "Zoek in alles",
"Documents" : "Documenten",
@@ -123,7 +120,6 @@ OC.L10N.register(
"Images" : "Afbeeldingen",
"Videos" : "Video's",
"Filters" : "Filters",
"Back to filters" : "Terug naar filters",
"Appearance" : "Uiterlijk",
"Show hidden files" : "Toon verborgen bestanden",
"Show file type column" : "Toon bestandstypekolom",
@@ -132,7 +128,6 @@ OC.L10N.register(
"General" : "Algemeen",
"Sort favorites first" : "Sorteer eerst favorieten",
"Sort folders before files" : "Sorteer mappen voor bestanden",
"Enable folder tree view" : "Schakel mappenboom weergave in",
"Default view" : "Standaardweergave",
"All files" : "Alle bestanden",
"Personal files" : "Persoonlijke bestanden",
@@ -157,8 +152,6 @@ OC.L10N.register(
"Warn before changing a file extension" : "Waarschuw voordat een bestand extensie wordt gewijzigd",
"Warn before deleting a file" : "Waarschuwen voor verwijderen bestand",
"WebDAV URL" : "WebDAV URL",
"Create an app password" : "Maak een app wachtwoord",
"Required for WebDAV authentication because Two-Factor Authentication is enabled for this account." : "Verplicht voor WebDAV authenticatie omdat Twee-Factor Authenticatie is ingeschakeld voor dit account.",
"How to access files using WebDAV" : "Hoe bestanden te benaderen met WebDAV",
"Total rows summary" : "Aantal rijen samenvatting",
"Toggle selection for all files and folders" : "Wijzig selectie voor alle bestanden en mappen",
@@ -235,9 +228,6 @@ OC.L10N.register(
"Removing the file extension \"{old}\" may render the file unreadable." : "Verwijderen van de extensie {old} kan ervoor zorgen dat het bestand niet meer gelezen kan worden.",
"Adding the file extension \"{new}\" may render the file unreadable." : "Toevoegen van de extensie {new} kan ervoor zorgen dat het bestand niet meer gelezen kan worden.",
"Do not show this dialog again." : "Laat dit dialoogvenster niet meer zien.",
"Rename file to hidden" : "Hernoem bestand naar verborgen",
"Prefixing a filename with a dot may render the file hidden." : "Een bestand laten starten met een punt kan het bestand verbergen.",
"Are you sure you want to rename the file to \"{filename}\"?" : "Weet je zeker dat je het bestand wil hernoemen naar \"{filename}\"?",
"Cancel" : "Annuleren",
"Rename" : "Naam wijzigen",
"Select file or folder to link to" : "Selecteer een bestand of map om naar te linken",
@@ -252,7 +242,6 @@ OC.L10N.register(
"Error during upload: {message}" : "Fout tijdens upload: {message}",
"Error during upload, status code {status}" : "Fout tijdens upload, status code {status}",
"Unknown error during upload" : "Onbekende fout tijdens upload",
"File list is reloading" : "Bestanden lijst wordt opnieuw geladen",
"Loading current folder" : "Laden huidige map",
"Retry" : "Opnieuw",
"No files in here" : "Hier geen bestanden",
@@ -282,9 +271,6 @@ OC.L10N.register(
"Failed to convert files: {message}" : "Conversie van bestanden mislukt: {message} ",
"All files failed to be converted" : "De conversie van alle bestanden is mislukt",
"One file could not be converted: {message}" : "Een bestand kon niet worden geconverteerd: {message}",
"_%n file could not be converted_::_%n files could not be converted_" : ["%n bestand kon niet worden geconverteerd","%n bestanden konden niet worden geconverteerd"],
"_%n file converted_::_%n files converted_" : ["%n bestand geconverteerd","%n bestanden geconverteerd"],
"Files converted" : "Bestanden geconverteerd",
"Failed to convert files" : "Conversie van bestanden mislukt",
"Converting file …" : "Bestand converteren …",
"File successfully converted" : "Bestand succesvol geconverteerd",
@@ -320,9 +306,7 @@ OC.L10N.register(
"The files are locked" : "De bestanden zijn vergrendeld",
"The file does not exist anymore" : "Dit bestand bestaat niet meer",
"Moving \"{source}\" to \"{destination}\" …" : "Verplaatsen \"{source}\" naar \"{destination}\" …",
"Moving {count} files to \"{destination}\" …" : "{count} bestanden aan het verplaatsen naar \"{destination}\" …",
"Copying \"{source}\" to \"{destination}\" …" : "Kopieren \"{source}\" naar \"{destination}\" …",
"Copying {count} files to \"{destination}\" …" : "{count}bestanden aan het kopiëren naar \"{destination}\" …",
"Choose destination" : "Kies bestemming",
"Copy to {target}" : "Kopieer naar {target}",
"Move to {target}" : "Verplaats naar {target}",
@@ -337,8 +321,6 @@ OC.L10N.register(
"Retry and close" : "Probeer opnieuw en sluiten",
"Open online" : "Open online",
"Details" : "Details",
"Open the details sidebar" : "Open de details zijbalk",
"Unfavorite" : "Favoriet weghalen",
"View in folder" : "Bekijken in map",
"Type" : "Type",
"Created new folder \"{name}\"" : "Nieuwe map \"¨{name}\" gemaakt.",
@@ -347,7 +329,6 @@ OC.L10N.register(
"Templates" : "Sjablonen",
"New template folder" : "Nieuwe sjablonenmap",
"In folder" : "In map",
"Pick folder to search in" : "Kies map om in te zoeken",
"Search in all files" : "Zoeken in alle bestanden",
"Search in folder: {folder}" : "Zoeken in map: {folder}",
"One of the dropped files could not be processed" : "Een van de bestanden kon niet verwerkt worden.",
-19
View File
@@ -77,7 +77,6 @@
"Go to the \"{dir}\" directory" : "Ga naar de \"{dir}\" map",
"Current directory path" : "Huidig directory pad",
"Share" : "Delen",
"Reload content" : "Laad inhoud opnieuw",
"Your have used your space quota and cannot upload files anymore" : "Je hebt je ruimtequotum gebruikt en kan geen bestanden meer uploaden",
"You do not have permission to upload or create files here." : "Je hebt geen toestemming om hier bestanden te uploaden of aan te maken.",
"Drag and drop files here to upload" : "Drag en drop bestanden hier om te uploaden",
@@ -93,7 +92,6 @@
"Another entry with the same name already exists." : "Er bestaat al een ander item met dezelfde naam",
"Invalid filename." : "Ongeldige bestandsnaam",
"Rename file" : "Bestand hernoemen",
"Recently created" : "Recentelijk gemaakt",
"Folder" : "Map",
"Unknown file type" : "Onbekend bestandstype",
"{ext} image" : "{ext} afbeelding",
@@ -109,7 +107,6 @@
"Last 30 days" : "Laatste 30 dagen",
"This year ({year})" : "Dit jaar ({year})",
"Last year ({year})" : "Afgelopen jaar ({year})",
"Custom range" : "Aangepast bereik",
"Custom date range" : "Aangepast datumbereik",
"Search everywhere" : "Zoek in alles",
"Documents" : "Documenten",
@@ -121,7 +118,6 @@
"Images" : "Afbeeldingen",
"Videos" : "Video's",
"Filters" : "Filters",
"Back to filters" : "Terug naar filters",
"Appearance" : "Uiterlijk",
"Show hidden files" : "Toon verborgen bestanden",
"Show file type column" : "Toon bestandstypekolom",
@@ -130,7 +126,6 @@
"General" : "Algemeen",
"Sort favorites first" : "Sorteer eerst favorieten",
"Sort folders before files" : "Sorteer mappen voor bestanden",
"Enable folder tree view" : "Schakel mappenboom weergave in",
"Default view" : "Standaardweergave",
"All files" : "Alle bestanden",
"Personal files" : "Persoonlijke bestanden",
@@ -155,8 +150,6 @@
"Warn before changing a file extension" : "Waarschuw voordat een bestand extensie wordt gewijzigd",
"Warn before deleting a file" : "Waarschuwen voor verwijderen bestand",
"WebDAV URL" : "WebDAV URL",
"Create an app password" : "Maak een app wachtwoord",
"Required for WebDAV authentication because Two-Factor Authentication is enabled for this account." : "Verplicht voor WebDAV authenticatie omdat Twee-Factor Authenticatie is ingeschakeld voor dit account.",
"How to access files using WebDAV" : "Hoe bestanden te benaderen met WebDAV",
"Total rows summary" : "Aantal rijen samenvatting",
"Toggle selection for all files and folders" : "Wijzig selectie voor alle bestanden en mappen",
@@ -233,9 +226,6 @@
"Removing the file extension \"{old}\" may render the file unreadable." : "Verwijderen van de extensie {old} kan ervoor zorgen dat het bestand niet meer gelezen kan worden.",
"Adding the file extension \"{new}\" may render the file unreadable." : "Toevoegen van de extensie {new} kan ervoor zorgen dat het bestand niet meer gelezen kan worden.",
"Do not show this dialog again." : "Laat dit dialoogvenster niet meer zien.",
"Rename file to hidden" : "Hernoem bestand naar verborgen",
"Prefixing a filename with a dot may render the file hidden." : "Een bestand laten starten met een punt kan het bestand verbergen.",
"Are you sure you want to rename the file to \"{filename}\"?" : "Weet je zeker dat je het bestand wil hernoemen naar \"{filename}\"?",
"Cancel" : "Annuleren",
"Rename" : "Naam wijzigen",
"Select file or folder to link to" : "Selecteer een bestand of map om naar te linken",
@@ -250,7 +240,6 @@
"Error during upload: {message}" : "Fout tijdens upload: {message}",
"Error during upload, status code {status}" : "Fout tijdens upload, status code {status}",
"Unknown error during upload" : "Onbekende fout tijdens upload",
"File list is reloading" : "Bestanden lijst wordt opnieuw geladen",
"Loading current folder" : "Laden huidige map",
"Retry" : "Opnieuw",
"No files in here" : "Hier geen bestanden",
@@ -280,9 +269,6 @@
"Failed to convert files: {message}" : "Conversie van bestanden mislukt: {message} ",
"All files failed to be converted" : "De conversie van alle bestanden is mislukt",
"One file could not be converted: {message}" : "Een bestand kon niet worden geconverteerd: {message}",
"_%n file could not be converted_::_%n files could not be converted_" : ["%n bestand kon niet worden geconverteerd","%n bestanden konden niet worden geconverteerd"],
"_%n file converted_::_%n files converted_" : ["%n bestand geconverteerd","%n bestanden geconverteerd"],
"Files converted" : "Bestanden geconverteerd",
"Failed to convert files" : "Conversie van bestanden mislukt",
"Converting file …" : "Bestand converteren …",
"File successfully converted" : "Bestand succesvol geconverteerd",
@@ -318,9 +304,7 @@
"The files are locked" : "De bestanden zijn vergrendeld",
"The file does not exist anymore" : "Dit bestand bestaat niet meer",
"Moving \"{source}\" to \"{destination}\" …" : "Verplaatsen \"{source}\" naar \"{destination}\" …",
"Moving {count} files to \"{destination}\" …" : "{count} bestanden aan het verplaatsen naar \"{destination}\" …",
"Copying \"{source}\" to \"{destination}\" …" : "Kopieren \"{source}\" naar \"{destination}\" …",
"Copying {count} files to \"{destination}\" …" : "{count}bestanden aan het kopiëren naar \"{destination}\" …",
"Choose destination" : "Kies bestemming",
"Copy to {target}" : "Kopieer naar {target}",
"Move to {target}" : "Verplaats naar {target}",
@@ -335,8 +319,6 @@
"Retry and close" : "Probeer opnieuw en sluiten",
"Open online" : "Open online",
"Details" : "Details",
"Open the details sidebar" : "Open de details zijbalk",
"Unfavorite" : "Favoriet weghalen",
"View in folder" : "Bekijken in map",
"Type" : "Type",
"Created new folder \"{name}\"" : "Nieuwe map \"¨{name}\" gemaakt.",
@@ -345,7 +327,6 @@
"Templates" : "Sjablonen",
"New template folder" : "Nieuwe sjablonenmap",
"In folder" : "In map",
"Pick folder to search in" : "Kies map om in te zoeken",
"Search in all files" : "Zoeken in alle bestanden",
"Search in folder: {folder}" : "Zoeken in map: {folder}",
"One of the dropped files could not be processed" : "Een van de bestanden kon niet verwerkt worden.",
+8 -26
View File
@@ -3,13 +3,13 @@ OC.L10N.register(
{
"You are not logged in" : "Je bent niet ingelogd",
"Permission denied" : "Toestemming geweigerd",
"Forbidden to manage local mounts" : "Niet toegestaan lokale aankoppelpunten te beheren",
"Forbidden to manage local mounts" : "Niet toegestaan lokale koppelpunten te beheren",
"Storage with ID \"%d\" not found" : "Opslag met ID \"%d\" niet gevonden",
"Invalid backend or authentication mechanism class" : "Ongeldige backend of authenticatie mechanisme klasse",
"Invalid mount point" : "Ongeldig aankoppelpunt",
"Objectstore forbidden" : "Objectopslag verboden",
"Invalid storage backend \"%s\"" : "Ongeldige backend \"%s\"",
"Not permitted to use backend \"%s\"" : "Niet toegestaan om backend \"%s\" te gebruiken",
"Invalid storage backend \"%s\"" : "Ongeldig opslagsysteem \"%s\"",
"Not permitted to use backend \"%s\"" : "Niet toegestaan om \"%s\" te gebruiken",
"Not permitted to use authentication mechanism \"%s\"" : "Niet toegestaan om authenticatiemechanisme \"%s\" te gebruiken",
"Unsatisfied backend parameters" : "Onvoldoende backend parameters",
"Unsatisfied authentication mechanism parameters" : "Onvoldoende authenticatiemechanisme parameters",
@@ -52,7 +52,6 @@ OC.L10N.register(
"Enable Path Style" : "Padstijl inschakelen",
"Legacy (v2) authentication" : "Verouderde (v2) authenticatie",
"Enable multipart copy" : "Meervoudig kopiëren inschakelen",
"Use presigned S3 url" : "Gebruik presigned S3 url",
"SSE-C encryption key" : "SSE-C versleutelingscode",
"WebDAV" : "WebDAV",
"URL" : "URL",
@@ -96,8 +95,6 @@ OC.L10N.register(
"Never" : "Nooit",
"Once every direct access" : "Een keer bij elke directe toegang",
"Always" : "Altijd",
"Mount options" : "Aankoppel opties",
"Check filesystem changes" : "Controleer bestandssysteem wijzigingen",
"Read only" : "Alleen-lezen",
"Enable previews" : "Voorbeeldweergave inschakelen",
"Enable sharing" : "Delen inschakelen",
@@ -108,16 +105,10 @@ OC.L10N.register(
"Restricted to" : "Beperkt tot",
"Actions" : "Acties",
"Checking …" : "Controleren ...",
"Recheck status" : "Hercontroleer status",
"Delete" : "Verwijderen",
"System provided storage" : "Door het systeem geleverde opslag",
"Saved" : "Bewaard",
"Error while saving" : "Fout bij opslaan",
"Saved allowed backends" : "Sla toegestane backends op",
"Failed to save allowed backends" : "Opslaan van toegestane backends mislukt",
"Advanced options for external storage mounts" : "Geavanceerde opties voor externe aankoppelpunten ",
"Allow people to mount external storage" : "Toestaan dat mensen externe opslag aankoppelen",
"External storage backends people are allowed to mount" : "Externe opslag backend die personen mogen gebruiken om aan te koppelen",
"Error generating key pair" : "Fout bij genereren sleutelpaar",
"Key size" : "Sleutellengte",
"Generate keys" : "Sleutels genereren",
@@ -126,16 +117,10 @@ OC.L10N.register(
"To access the storage, you need to provide the authentication credentials." : "Om toegang te krijgen tot de opslag, moeten de authenticatiegegevens worden geleverd.",
"Enter the storage login" : "Voer de loginnaam in voor de opslag",
"Enter the storage password" : "Voer het wachtwoord in voor de opslag",
"External storage enables you to mount external storage services and devices as secondary Nextcloud storage devices." : "Externe opslag geeft je de mogelijkheid om externe opslag diensten en apparaten aan te koppelen als secundaire Nextcloud opslag apparaten.",
"You may also allow people to mount their own external storage services." : "Je kan ook personen toestaan om hun eigen externe opslag diensten aan te koppelen",
"The cURL support in PHP is not enabled or installed." : "cURL ondersteuning in PHP is niet ingeschakeld of geïnstalleerd.",
"The FTP support in PHP is not enabled or installed." : "FTP ondersteuning in PHP is niet ingeschakeld of geïnstalleerd,",
"{module} is not installed." : "{module} is niet geïnstalleerd.",
"Dependant backends" : "Afhankelijke backends",
"No external storage configured or you do not have the permission to configure them" : "Geen externe opslag geconfigureerd of je hebt geen machtigingen om deze te configureren",
"Add external storage" : "Voeg externe opslag toe",
"Global credentials saved" : "Globale inloggegevens opgeslagen",
"Could not save global credentials" : "Kon globale inloggegevens niet opslaan",
"Global credentials can be used to authenticate with multiple external storages that have the same credentials." : "Globale inloggegevens kunnen worden gebruikt met meerdere externe opslagsystemen met dezelfde inloggegevens.",
"Saving …" : "Opslaan ...",
"Save" : "Opslaan",
@@ -149,7 +134,7 @@ OC.L10N.register(
"We were unable to check the external storage {basename}" : "We konden de externe opslag {basename} niet controleren",
"Examine this faulty external storage configuration" : "Onderzoek deze foutieve externe opslagconfiguratie",
"Open in Files" : "Openen in Bestanden",
"External mount error" : "Fout met extern aankoppelen",
"External mount error" : "Fout met extern aankoppelpunt",
"There was an error with this external storage. Do you want to review this mount point config in the settings page?" : "Er is een fout opgetreden bij deze externe opslag. Wil je de configuratie voor dit aankoppelpunt bekijken op de instellingenpagina?",
"Open settings" : "Instellingen openen",
"Ignore" : "Negeren",
@@ -164,7 +149,6 @@ OC.L10N.register(
"System" : "Systeem",
"Connected" : "Verbonden",
"Error" : "Fout",
"Indeterminate" : "Tussenliggend",
"Incomplete configuration" : "Onvolledige configuratie",
"Unauthorized" : "Niet toegestaan",
"Network error" : "Netwerk fout",
@@ -174,19 +158,17 @@ OC.L10N.register(
"OAuth2" : "OAuth2",
"Client ID" : "Client ID",
"Client secret" : "Client secret",
"The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "De cURL ondersteuning in PHP is niet ingeschakeld of geïnstalleerd. Aankoppelen van %s is niet mogelijk. Vraag je systeembeheerder dit te installeren.",
"The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "De FTP ondersteuning in PHP is niet ingeschakeld of geïnstalleerd. Aankoppelen van %s is niet mogelijk. Vraag je systeembeheerder dit te installeren.",
"\"%1$s\" is not installed. Mounting of %2$s is not possible. Please ask your system administrator to install it." : "\"%1$s\" is niet geïnstalleerd. Aankoppelen van %2$s is niet mogelijk. Vraag je systeembeheerder om dit te installeren.",
"The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Curl ondersteuning in PHP is niet ingeschakeld of geïnstalleerd. Aankoppelen van %s is niet mogelijk. Vraag je systeembeheerder dit te installeren.",
"The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "FTP ondersteuning in PHP is niet ingeschakeld of geïnstalleerd. Aankoppelen van %s is niet mogelijk. Vraag je beheerder dit te installeren.",
"\"%1$s\" is not installed. Mounting of %2$s is not possible. Please ask your system administrator to install it." : "\"%1$s\" is niet geïnstalleerd. Aankoppelen van %2$s is niet mogelijk. Vraag je beheerder om dit te installeren.",
"Checking storage …" : "Controle van opslag …",
"Type to select account or group." : "Typ om account of groep te selecteren.",
"(Group)" : "(Groep)",
"Check for changes" : "Controleren op wijzigingen",
"Disconnect" : "Verbinding verbreken",
"Unknown backend: {backendName}" : "Onbekende backend: {backendName}",
"Unknown backend: {backendName}" : "Onbekend back-end: {backendName}",
"Admin defined" : "Beheerder gedefinieerd",
"Automatic status checking is disabled due to the large number of configured storages, click to check status" : "Automatische statuscontrole is uitgeschakeld vanwege het grote aantal geconfigureerde opslagplaatsen. Klik om de status te controleren",
"Are you sure you want to disconnect this external storage?" : "Weet je zeker dat je deze externe opslag wil loskoppelen? ",
"It will make the storage unavailable in {instanceName} and will lead to a deletion of these files and folders on any sync client that is currently connected but will not delete any files and folders on the external storage itself." : "Het maakt de opslag onbereikbaar in {instanceName} en zal leiden tot het verwijderen van bestanden en mappen op elke sync client die op dit moment verbonden is maar zal geen bestanden en mappen verwijderen van de externe opslag zelf.",
"Delete storage?" : "Opslag verwijderen?",
"Click to recheck the configuration" : "Klik om de configuratie opnieuw te controleren",
"Saving …" : "Opslaan …",
+8 -26
View File
@@ -1,13 +1,13 @@
{ "translations": {
"You are not logged in" : "Je bent niet ingelogd",
"Permission denied" : "Toestemming geweigerd",
"Forbidden to manage local mounts" : "Niet toegestaan lokale aankoppelpunten te beheren",
"Forbidden to manage local mounts" : "Niet toegestaan lokale koppelpunten te beheren",
"Storage with ID \"%d\" not found" : "Opslag met ID \"%d\" niet gevonden",
"Invalid backend or authentication mechanism class" : "Ongeldige backend of authenticatie mechanisme klasse",
"Invalid mount point" : "Ongeldig aankoppelpunt",
"Objectstore forbidden" : "Objectopslag verboden",
"Invalid storage backend \"%s\"" : "Ongeldige backend \"%s\"",
"Not permitted to use backend \"%s\"" : "Niet toegestaan om backend \"%s\" te gebruiken",
"Invalid storage backend \"%s\"" : "Ongeldig opslagsysteem \"%s\"",
"Not permitted to use backend \"%s\"" : "Niet toegestaan om \"%s\" te gebruiken",
"Not permitted to use authentication mechanism \"%s\"" : "Niet toegestaan om authenticatiemechanisme \"%s\" te gebruiken",
"Unsatisfied backend parameters" : "Onvoldoende backend parameters",
"Unsatisfied authentication mechanism parameters" : "Onvoldoende authenticatiemechanisme parameters",
@@ -50,7 +50,6 @@
"Enable Path Style" : "Padstijl inschakelen",
"Legacy (v2) authentication" : "Verouderde (v2) authenticatie",
"Enable multipart copy" : "Meervoudig kopiëren inschakelen",
"Use presigned S3 url" : "Gebruik presigned S3 url",
"SSE-C encryption key" : "SSE-C versleutelingscode",
"WebDAV" : "WebDAV",
"URL" : "URL",
@@ -94,8 +93,6 @@
"Never" : "Nooit",
"Once every direct access" : "Een keer bij elke directe toegang",
"Always" : "Altijd",
"Mount options" : "Aankoppel opties",
"Check filesystem changes" : "Controleer bestandssysteem wijzigingen",
"Read only" : "Alleen-lezen",
"Enable previews" : "Voorbeeldweergave inschakelen",
"Enable sharing" : "Delen inschakelen",
@@ -106,16 +103,10 @@
"Restricted to" : "Beperkt tot",
"Actions" : "Acties",
"Checking …" : "Controleren ...",
"Recheck status" : "Hercontroleer status",
"Delete" : "Verwijderen",
"System provided storage" : "Door het systeem geleverde opslag",
"Saved" : "Bewaard",
"Error while saving" : "Fout bij opslaan",
"Saved allowed backends" : "Sla toegestane backends op",
"Failed to save allowed backends" : "Opslaan van toegestane backends mislukt",
"Advanced options for external storage mounts" : "Geavanceerde opties voor externe aankoppelpunten ",
"Allow people to mount external storage" : "Toestaan dat mensen externe opslag aankoppelen",
"External storage backends people are allowed to mount" : "Externe opslag backend die personen mogen gebruiken om aan te koppelen",
"Error generating key pair" : "Fout bij genereren sleutelpaar",
"Key size" : "Sleutellengte",
"Generate keys" : "Sleutels genereren",
@@ -124,16 +115,10 @@
"To access the storage, you need to provide the authentication credentials." : "Om toegang te krijgen tot de opslag, moeten de authenticatiegegevens worden geleverd.",
"Enter the storage login" : "Voer de loginnaam in voor de opslag",
"Enter the storage password" : "Voer het wachtwoord in voor de opslag",
"External storage enables you to mount external storage services and devices as secondary Nextcloud storage devices." : "Externe opslag geeft je de mogelijkheid om externe opslag diensten en apparaten aan te koppelen als secundaire Nextcloud opslag apparaten.",
"You may also allow people to mount their own external storage services." : "Je kan ook personen toestaan om hun eigen externe opslag diensten aan te koppelen",
"The cURL support in PHP is not enabled or installed." : "cURL ondersteuning in PHP is niet ingeschakeld of geïnstalleerd.",
"The FTP support in PHP is not enabled or installed." : "FTP ondersteuning in PHP is niet ingeschakeld of geïnstalleerd,",
"{module} is not installed." : "{module} is niet geïnstalleerd.",
"Dependant backends" : "Afhankelijke backends",
"No external storage configured or you do not have the permission to configure them" : "Geen externe opslag geconfigureerd of je hebt geen machtigingen om deze te configureren",
"Add external storage" : "Voeg externe opslag toe",
"Global credentials saved" : "Globale inloggegevens opgeslagen",
"Could not save global credentials" : "Kon globale inloggegevens niet opslaan",
"Global credentials can be used to authenticate with multiple external storages that have the same credentials." : "Globale inloggegevens kunnen worden gebruikt met meerdere externe opslagsystemen met dezelfde inloggegevens.",
"Saving …" : "Opslaan ...",
"Save" : "Opslaan",
@@ -147,7 +132,7 @@
"We were unable to check the external storage {basename}" : "We konden de externe opslag {basename} niet controleren",
"Examine this faulty external storage configuration" : "Onderzoek deze foutieve externe opslagconfiguratie",
"Open in Files" : "Openen in Bestanden",
"External mount error" : "Fout met extern aankoppelen",
"External mount error" : "Fout met extern aankoppelpunt",
"There was an error with this external storage. Do you want to review this mount point config in the settings page?" : "Er is een fout opgetreden bij deze externe opslag. Wil je de configuratie voor dit aankoppelpunt bekijken op de instellingenpagina?",
"Open settings" : "Instellingen openen",
"Ignore" : "Negeren",
@@ -162,7 +147,6 @@
"System" : "Systeem",
"Connected" : "Verbonden",
"Error" : "Fout",
"Indeterminate" : "Tussenliggend",
"Incomplete configuration" : "Onvolledige configuratie",
"Unauthorized" : "Niet toegestaan",
"Network error" : "Netwerk fout",
@@ -172,19 +156,17 @@
"OAuth2" : "OAuth2",
"Client ID" : "Client ID",
"Client secret" : "Client secret",
"The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "De cURL ondersteuning in PHP is niet ingeschakeld of geïnstalleerd. Aankoppelen van %s is niet mogelijk. Vraag je systeembeheerder dit te installeren.",
"The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "De FTP ondersteuning in PHP is niet ingeschakeld of geïnstalleerd. Aankoppelen van %s is niet mogelijk. Vraag je systeembeheerder dit te installeren.",
"\"%1$s\" is not installed. Mounting of %2$s is not possible. Please ask your system administrator to install it." : "\"%1$s\" is niet geïnstalleerd. Aankoppelen van %2$s is niet mogelijk. Vraag je systeembeheerder om dit te installeren.",
"The cURL support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "Curl ondersteuning in PHP is niet ingeschakeld of geïnstalleerd. Aankoppelen van %s is niet mogelijk. Vraag je systeembeheerder dit te installeren.",
"The FTP support in PHP is not enabled or installed. Mounting of %s is not possible. Please ask your system administrator to install it." : "FTP ondersteuning in PHP is niet ingeschakeld of geïnstalleerd. Aankoppelen van %s is niet mogelijk. Vraag je beheerder dit te installeren.",
"\"%1$s\" is not installed. Mounting of %2$s is not possible. Please ask your system administrator to install it." : "\"%1$s\" is niet geïnstalleerd. Aankoppelen van %2$s is niet mogelijk. Vraag je beheerder om dit te installeren.",
"Checking storage …" : "Controle van opslag …",
"Type to select account or group." : "Typ om account of groep te selecteren.",
"(Group)" : "(Groep)",
"Check for changes" : "Controleren op wijzigingen",
"Disconnect" : "Verbinding verbreken",
"Unknown backend: {backendName}" : "Onbekende backend: {backendName}",
"Unknown backend: {backendName}" : "Onbekend back-end: {backendName}",
"Admin defined" : "Beheerder gedefinieerd",
"Automatic status checking is disabled due to the large number of configured storages, click to check status" : "Automatische statuscontrole is uitgeschakeld vanwege het grote aantal geconfigureerde opslagplaatsen. Klik om de status te controleren",
"Are you sure you want to disconnect this external storage?" : "Weet je zeker dat je deze externe opslag wil loskoppelen? ",
"It will make the storage unavailable in {instanceName} and will lead to a deletion of these files and folders on any sync client that is currently connected but will not delete any files and folders on the external storage itself." : "Het maakt de opslag onbereikbaar in {instanceName} en zal leiden tot het verwijderen van bestanden en mappen op elke sync client die op dit moment verbonden is maar zal geen bestanden en mappen verwijderen van de externe opslag zelf.",
"Delete storage?" : "Opslag verwijderen?",
"Click to recheck the configuration" : "Klik om de configuratie opnieuw te controleren",
"Saving …" : "Opslaan …",
@@ -14,14 +14,19 @@ use OCA\Files_External\Event\StorageUpdatedEvent;
use OCA\Files_External\Lib\StorageConfig;
use OCA\Files_External\MountConfig;
use OCP\IGroup;
use Override;
/**
* Service class to manage global external storage
*/
class GlobalStoragesService extends StoragesService {
#[Override]
protected function triggerHooks(StorageConfig $storage, $signal): void {
/**
* Triggers $signal for all applicable users of the given
* storage
*
* @param StorageConfig $storage storage data
* @param string $signal signal to trigger
*/
protected function triggerHooks(StorageConfig $storage, $signal) {
// FIXME: Use as expression in empty once PHP 5.4 support is dropped
$applicableUsers = $storage->getApplicableUsers();
$applicableGroups = $storage->getApplicableGroups();
@@ -50,8 +55,15 @@ class GlobalStoragesService extends StoragesService {
);
}
#[Override]
protected function triggerChangeHooks(StorageConfig $oldStorage, StorageConfig $newStorage): void {
/**
* Triggers signal_create_mount or signal_delete_mount to
* accommodate for additions/deletions in applicableUsers
* and applicableGroups fields.
*
* @param StorageConfig $oldStorage old storage config
* @param StorageConfig $newStorage new storage config
*/
protected function triggerChangeHooks(StorageConfig $oldStorage, StorageConfig $newStorage) {
// if mount point changed, it's like a deletion + creation
if ($oldStorage->getMountPoint() !== $newStorage->getMountPoint()) {
$this->eventDispatcher->dispatchTyped(new StorageDeletedEvent($oldStorage));
@@ -127,13 +139,16 @@ class GlobalStoragesService extends StoragesService {
}
}
#[Override]
public function getVisibilityType(): int {
/**
* Get the visibility type for this controller, used in validation
*
* @return int BackendService::VISIBILITY_* constants
*/
public function getVisibilityType() {
return BackendService::VISIBILITY_ADMIN;
}
#[Override]
protected function isApplicable(StorageConfig $config): bool {
protected function isApplicable(StorageConfig $config) {
return true;
}
@@ -142,14 +157,16 @@ class GlobalStoragesService extends StoragesService {
*
* @return StorageConfig[] map of storage id to storage config
*/
public function getStorageForAllUsers(): array {
public function getStorageForAllUsers() {
$mounts = $this->dbConfig->getAllMounts();
$configs = array_map([$this, 'getStorageConfigFromDBMount'], $mounts);
$configs = array_filter($configs, function ($config) {
return $config instanceof StorageConfig;
});
$keys = array_map(static fn (StorageConfig $config) => $config->getId(), $configs);
$keys = array_map(function (StorageConfig $config) {
return $config->getId();
}, $configs);
return array_combine($keys, $configs);
}
@@ -31,10 +31,14 @@ use Psr\Log\LoggerInterface;
/**
* Service class to manage external storage
*
* @psalm-import-type ExternalMountInfo from DBConfigService
*/
abstract class StoragesService {
/**
* @param BackendService $backendService
* @param DBConfigService $dbConfig
* @param IEventDispatcher $eventDispatcher
*/
public function __construct(
protected BackendService $backendService,
protected DBConfigService $dbConfig,
@@ -43,21 +47,24 @@ abstract class StoragesService {
) {
}
/**
* @return list<ExternalMountInfo>
*/
protected function readDBConfig(): array {
protected function readDBConfig() {
return $this->dbConfig->getAdminMounts();
}
protected function getStorageConfigFromDBMount(array $mount): ?StorageConfig {
$applicableUsers = array_filter($mount['applicable'], static fn (array $applicable): bool
=> $applicable['type'] === DBConfigService::APPLICABLE_TYPE_USER);
$applicableUsers = array_map(static fn (array $applicable) => $applicable['value'], $applicableUsers);
protected function getStorageConfigFromDBMount(array $mount) {
$applicableUsers = array_filter($mount['applicable'], function ($applicable) {
return $applicable['type'] === DBConfigService::APPLICABLE_TYPE_USER;
});
$applicableUsers = array_map(function ($applicable) {
return $applicable['value'];
}, $applicableUsers);
$applicableGroups = array_filter($mount['applicable'], static fn (array $applicable): bool
=> $applicable['type'] === DBConfigService::APPLICABLE_TYPE_GROUP);
$applicableGroups = array_map(static fn (array $applicable) => $applicable['value'], $applicableGroups);
$applicableGroups = array_filter($mount['applicable'], function ($applicable) {
return $applicable['type'] === DBConfigService::APPLICABLE_TYPE_GROUP;
});
$applicableGroups = array_map(function ($applicable) {
return $applicable['value'];
}, $applicableGroups);
try {
$config = $this->createStorage(
@@ -92,14 +99,18 @@ abstract class StoragesService {
/**
* Read the external storage config
*
* @return array<int, StorageConfig> map of storage id to storage config
* @return array map of storage id to storage config
*/
protected function readConfig(): array {
protected function readConfig() {
$mounts = $this->readDBConfig();
$configs = array_map($this->getStorageConfigFromDBMount(...), $mounts);
$configs = array_filter($configs);
$configs = array_map([$this, 'getStorageConfigFromDBMount'], $mounts);
$configs = array_filter($configs, function ($config) {
return $config instanceof StorageConfig;
});
$keys = array_map(static fn (StorageConfig $config): int => $config->getId(), $configs);
$keys = array_map(function (StorageConfig $config) {
return $config->getId();
}, $configs);
return array_combine($keys, $configs);
}
@@ -128,15 +139,18 @@ abstract class StoragesService {
/**
* Check whether this storage service should provide access to a storage
*
* @param StorageConfig $config
* @return bool
*/
abstract protected function isApplicable(StorageConfig $config): bool;
abstract protected function isApplicable(StorageConfig $config);
/**
* Gets all storages, valid or not
*
* @return StorageConfig[] array of storage configs
*/
public function getAllStorages(): array {
public function getAllStorages() {
return $this->readConfig();
}
@@ -145,16 +159,18 @@ abstract class StoragesService {
*
* @return StorageConfig[]
*/
public function getStorages(): array {
return array_filter($this->getAllStorages(), $this->validateStorage(...));
public function getStorages() {
return array_filter($this->getAllStorages(), [$this, 'validateStorage']);
}
/**
* Validate storage
* FIXME: De-duplicate with StoragesController::validate()
*
* @param StorageConfig $storage
* @return bool
*/
protected function validateStorage(StorageConfig $storage): bool {
protected function validateStorage(StorageConfig $storage) {
/** @var Backend */
$backend = $storage->getBackend();
/** @var AuthMechanism */
@@ -164,19 +180,25 @@ abstract class StoragesService {
// not permitted to use backend
return false;
}
if (!$authMechanism->isVisibleFor($this->getVisibilityType())) {
// not permitted to use auth mechanism
return false;
}
// permitted to use auth mechanism
return $authMechanism->isVisibleFor($this->getVisibilityType());
return true;
}
/**
* Get the visibility type for this controller, used in validation
*
* @return BackendService::VISIBILITY_*
* @return int BackendService::VISIBILITY_* constants
*/
abstract public function getVisibilityType(): int;
abstract public function getVisibilityType();
protected function getType(): int {
/**
* @return integer
*/
protected function getType() {
return DBConfigService::MOUNT_TYPE_ADMIN;
}
@@ -187,7 +209,7 @@ abstract class StoragesService {
*
* @return StorageConfig storage config, with added id
*/
public function addStorage(StorageConfig $newStorage): StorageConfig {
public function addStorage(StorageConfig $newStorage) {
$allStorages = $this->readConfig();
$configId = $this->dbConfig->addMount(
@@ -253,7 +275,7 @@ abstract class StoragesService {
?array $applicableUsers = null,
?array $applicableGroups = null,
?int $priority = null,
): StorageConfig {
) {
$backend = $this->backendService->getBackend($backendIdentifier);
if (!$backend) {
$backend = new InvalidBackend($backendIdentifier);
@@ -291,7 +313,7 @@ abstract class StoragesService {
* @param string $mountType hook mount type param
* @param array $applicableArray array of applicable users/groups for which to trigger the hook
*/
protected function triggerApplicableHooks(string $signal, string $mountPoint, string $mountType, array $applicableArray): void {
protected function triggerApplicableHooks($signal, $mountPoint, $mountType, $applicableArray): void {
$this->eventDispatcher->dispatchTyped(new InvalidateMountCacheEvent(null));
foreach ($applicableArray as $applicable) {
Util::emitHook(
@@ -313,7 +335,7 @@ abstract class StoragesService {
* @param StorageConfig $storage storage data
* @param string $signal signal to trigger
*/
abstract protected function triggerHooks(StorageConfig $storage, string $signal): void;
abstract protected function triggerHooks(StorageConfig $storage, $signal);
/**
* Triggers signal_create_mount or signal_delete_mount to
@@ -323,7 +345,7 @@ abstract class StoragesService {
* @param StorageConfig $oldStorage old storage data
* @param StorageConfig $newStorage new storage data
*/
abstract protected function triggerChangeHooks(StorageConfig $oldStorage, StorageConfig $newStorage): void;
abstract protected function triggerChangeHooks(StorageConfig $oldStorage, StorageConfig $newStorage);
/**
* Update storage to the configuration
@@ -333,7 +355,7 @@ abstract class StoragesService {
* @return StorageConfig storage config
* @throws NotFoundException if the given storage does not exist in the config
*/
public function updateStorage(StorageConfig $updatedStorage): StorageConfig {
public function updateStorage(StorageConfig $updatedStorage) {
$id = $updatedStorage->getId();
$existingMount = $this->dbConfig->getMountById($id);
@@ -413,7 +435,7 @@ abstract class StoragesService {
*
* @throws NotFoundException if no storage was found with the given id
*/
public function removeStorage(int $id): void {
public function removeStorage(int $id) {
$existingMount = $this->dbConfig->getMountById($id);
if (!is_array($existingMount)) {
@@ -432,6 +454,29 @@ abstract class StoragesService {
$this->updateOverwriteHomeFolders();
}
/**
* Construct the storage implementation
*
* @param StorageConfig $storageConfig
* @return int
*/
private function getStorageId(StorageConfig $storageConfig) {
try {
$class = $storageConfig->getBackend()->getStorageClass();
/** @var \OC\Files\Storage\Storage $storage */
$storage = new $class($storageConfig->getBackendOptions());
// auth mechanism should fire first
$storage = $storageConfig->getBackend()->wrapStorage($storage);
$storage = $storageConfig->getAuthMechanism()->wrapStorage($storage);
/** @var \OC\Files\Storage\Storage $storage */
return $storage->getStorageCache()->getNumericId();
} catch (\Exception $e) {
return -1;
}
}
public function updateOverwriteHomeFolders(): void {
$appIdsList = $this->appConfig->getValueArray(FilesApplication::APP_ID, ConfigLexicon::OVERWRITES_HOME_FOLDERS);
@@ -13,7 +13,6 @@ use OCP\IAppConfig;
use OCP\IGroupManager;
use OCP\IUser;
use OCP\IUserSession;
use Override;
/**
* Service class to read global storages applicable to the user
@@ -34,8 +33,20 @@ class UserGlobalStoragesService extends GlobalStoragesService {
$this->userSession = $userSession;
}
#[Override]
protected function readDBConfig(): array {
/**
* Replace config hash ID with real IDs, for migrating legacy storages
*
* @param StorageConfig[] $storages Storages with real IDs
* @param StorageConfig[] $storagesWithConfigHash Storages with config hash IDs
*/
protected function setRealStorageIds(array &$storages, array $storagesWithConfigHash) {
// as a read-only view, storage IDs don't need to be real
foreach ($storagesWithConfigHash as $storage) {
$storages[$storage->getId()] = $storage;
}
}
protected function readDBConfig() {
$userMounts = $this->dbConfig->getAdminMountsFor(DBConfigService::APPLICABLE_TYPE_USER, $this->getUser()->getUID());
$globalMounts = $this->dbConfig->getAdminMountsFor(DBConfigService::APPLICABLE_TYPE_GLOBAL, null);
$groups = $this->groupManager->getUserGroupIds($this->getUser());
@@ -47,18 +58,18 @@ class UserGlobalStoragesService extends GlobalStoragesService {
return array_merge($userMounts, $groupMounts, $globalMounts);
}
#[Override]
public function addStorage(StorageConfig $newStorage): never {
throw new \DomainException('UserGlobalStoragesService writing disallowed');
}
#[Override]
public function updateStorage(StorageConfig $updatedStorage): never {
throw new \DomainException('UserGlobalStoragesService writing disallowed');
}
#[Override]
public function removeStorage(int $id): never {
/**
* @param integer $id
*/
public function removeStorage($id): never {
throw new \DomainException('UserGlobalStoragesService writing disallowed');
}
@@ -68,7 +79,7 @@ class UserGlobalStoragesService extends GlobalStoragesService {
*
* @return StorageConfig[]
*/
public function getUniqueStorages(): array {
public function getUniqueStorages() {
$storages = $this->getStorages();
$storagesByMountpoint = [];
@@ -105,17 +116,20 @@ class UserGlobalStoragesService extends GlobalStoragesService {
* @param StorageConfig $storage
* @return int
*/
protected function getPriorityType(StorageConfig $storage): int {
protected function getPriorityType(StorageConfig $storage) {
$applicableUsers = $storage->getApplicableUsers();
$applicableGroups = $storage->getApplicableGroups();
if ($applicableUsers && $applicableUsers[0] !== 'all') {
return 2;
}
return $applicableGroups ? 1 : 0;
if ($applicableGroups) {
return 1;
}
return 0;
}
protected function isApplicable(StorageConfig $config): bool {
protected function isApplicable(StorageConfig $config) {
$applicableUsers = $config->getApplicableUsers();
$applicableGroups = $config->getApplicableGroups();
@@ -141,7 +155,7 @@ class UserGlobalStoragesService extends GlobalStoragesService {
* @param IUser|null $user user to get the storages for, if not set the currently logged in user will be used
* @return StorageConfig[] array of storage configs
*/
public function getAllStoragesForUser(?IUser $user = null): array {
public function getAllStoragesForUser(?IUser $user = null) {
if (is_null($user)) {
$user = $this->getUser();
}
@@ -12,10 +12,10 @@ use OCA\Files_External\Event\StorageCreatedEvent;
use OCA\Files_External\Event\StorageDeletedEvent;
use OCA\Files_External\Lib\StorageConfig;
use OCA\Files_External\MountConfig;
use OCA\Files_External\NotFoundException;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IAppConfig;
use OCP\IUserSession;
use Override;
/**
* Service class to manage user external storage
@@ -38,8 +38,7 @@ class UserStoragesService extends StoragesService {
parent::__construct($backendService, $dbConfig, $eventDispatcher, $appConfig);
}
#[Override]
protected function readDBConfig(): array {
protected function readDBConfig() {
return $this->dbConfig->getUserMountsFor(DBConfigService::APPLICABLE_TYPE_USER, $this->getUser()->getUID());
}
@@ -50,7 +49,7 @@ class UserStoragesService extends StoragesService {
* @param StorageConfig $storage storage data
* @param string $signal signal to trigger
*/
protected function triggerHooks(StorageConfig $storage, string $signal): void {
protected function triggerHooks(StorageConfig $storage, $signal) {
$user = $this->getUser()->getUID();
// trigger hook for the current user
@@ -70,7 +69,7 @@ class UserStoragesService extends StoragesService {
* @param StorageConfig $oldStorage old storage data
* @param StorageConfig $newStorage new storage data
*/
protected function triggerChangeHooks(StorageConfig $oldStorage, StorageConfig $newStorage): void {
protected function triggerChangeHooks(StorageConfig $oldStorage, StorageConfig $newStorage) {
// if mount point changed, it's like a deletion + creation
if ($oldStorage->getMountPoint() !== $newStorage->getMountPoint()) {
$this->eventDispatcher->dispatchTyped(new StorageDeletedEvent($oldStorage));
@@ -80,19 +79,31 @@ class UserStoragesService extends StoragesService {
}
}
#[Override]
protected function getType(): int {
protected function getType() {
return DBConfigService::MOUNT_TYPE_PERSONAL;
}
#[Override]
public function addStorage(StorageConfig $newStorage): StorageConfig {
/**
* Add new storage to the configuration
*
* @param StorageConfig $newStorage storage attributes
*
* @return StorageConfig storage config, with added id
*/
public function addStorage(StorageConfig $newStorage) {
$newStorage->setApplicableUsers([$this->getUser()->getUID()]);
return parent::addStorage($newStorage);
}
#[Override]
public function updateStorage(StorageConfig $updatedStorage): StorageConfig {
/**
* Update storage to the configuration
*
* @param StorageConfig $updatedStorage storage attributes
*
* @return StorageConfig storage config
* @throws NotFoundException if the given storage does not exist in the config
*/
public function updateStorage(StorageConfig $updatedStorage) {
// verify ownership through $this->isApplicable() and otherwise throws an exception
$this->getStorage($updatedStorage->getId());
@@ -100,18 +111,20 @@ class UserStoragesService extends StoragesService {
return parent::updateStorage($updatedStorage);
}
#[Override]
/**
* Get the visibility type for this controller, used in validation
*
* @return int BackendService::VISIBILITY_* constants
*/
public function getVisibilityType(): int {
return BackendService::VISIBILITY_PERSONAL;
}
#[Override]
protected function isApplicable(StorageConfig $config): bool {
return ($config->getApplicableUsers() === [$this->getUser()->getUID()]) && $config->getType() === StorageConfig::MOUNT_TYPE_PERSONAL;
}
#[Override]
public function removeStorage(int $id): void {
public function removeStorage($id) {
// verify ownership through $this->isApplicable() and otherwise throws an exception
$this->getStorage($id);
parent::removeStorage($id);
@@ -96,6 +96,8 @@ return array(
'OCA\\Files_Sharing\\ResponseDefinitions' => $baseDir . '/../lib/ResponseDefinitions.php',
'OCA\\Files_Sharing\\Scanner' => $baseDir . '/../lib/Scanner.php',
'OCA\\Files_Sharing\\Settings\\Personal' => $baseDir . '/../lib/Settings/Personal.php',
'OCA\\Files_Sharing\\ShareBackend\\File' => $baseDir . '/../lib/ShareBackend/File.php',
'OCA\\Files_Sharing\\ShareBackend\\Folder' => $baseDir . '/../lib/ShareBackend/Folder.php',
'OCA\\Files_Sharing\\ShareTargetValidator' => $baseDir . '/../lib/ShareTargetValidator.php',
'OCA\\Files_Sharing\\SharedMount' => $baseDir . '/../lib/SharedMount.php',
'OCA\\Files_Sharing\\SharedStorage' => $baseDir . '/../lib/SharedStorage.php',
@@ -111,6 +111,8 @@ class ComposerStaticInitFiles_Sharing
'OCA\\Files_Sharing\\ResponseDefinitions' => __DIR__ . '/..' . '/../lib/ResponseDefinitions.php',
'OCA\\Files_Sharing\\Scanner' => __DIR__ . '/..' . '/../lib/Scanner.php',
'OCA\\Files_Sharing\\Settings\\Personal' => __DIR__ . '/..' . '/../lib/Settings/Personal.php',
'OCA\\Files_Sharing\\ShareBackend\\File' => __DIR__ . '/..' . '/../lib/ShareBackend/File.php',
'OCA\\Files_Sharing\\ShareBackend\\Folder' => __DIR__ . '/..' . '/../lib/ShareBackend/Folder.php',
'OCA\\Files_Sharing\\ShareTargetValidator' => __DIR__ . '/..' . '/../lib/ShareTargetValidator.php',
'OCA\\Files_Sharing\\SharedMount' => __DIR__ . '/..' . '/../lib/SharedMount.php',
'OCA\\Files_Sharing\\SharedStorage' => __DIR__ . '/..' . '/../lib/SharedStorage.php',
-3
View File
@@ -165,7 +165,6 @@ OC.L10N.register(
"Unshare" : "Lopeta jakaminen",
"Cannot copy, please copy the link manually" : "Kopioiminen ei onnistu. Kopioi linkki manuaalisesti",
"Copy internal link" : "Kopioi sisäinen linkki",
"For people who already have access" : "Henkilöille, joilla on jo käyttöoikeus",
"Internal link" : "Sisäinen linkki",
"Shared via link by {initiator}" : "Jaettu linkin kautta käyttäjältä {initiator}",
"File request ({label})" : "Tiedostopyyntö ({label})",
@@ -248,7 +247,6 @@ OC.L10N.register(
"Toggle list of others with access to this directory" : "Vaihda näkymää kansioon käyttöoikeuden omaavista käyttäjistä",
"Toggle list of others with access to this file" : "Vaihda näkymää tiedostoon käyttöoikeuden omaavista käyttäjistä",
"Shares" : "Jaot",
"Shares from apps or other sources which are not included in internal or external shares." : "Jaot muista sovelluksista tai lähteistä, jotka eivät sisälly sisäisiin tai ulkoisiin jakoihin.",
"Type names or teams" : "Kirjoita nimet tai tiimit",
"Type an email" : "Kirjoita sähköpostiosoite",
"Unable to load the shares list" : "Jakolistan haku epäonnistui",
@@ -257,7 +255,6 @@ OC.L10N.register(
"Shared with you by {owner}" : "{owner} jakoi tämän kanssasi",
"Internal shares" : "Sisäiset jaot",
"External shares" : "Ulkoiset jaot",
"Additional shares" : "Muut jaot",
"Link to a file" : "Linkki tiedostoon",
"_Accept share_::_Accept shares_" : ["Hyväksy jako","Hyväksy jaot"],
"Open in Files" : "Avaa tiedostosovelluksessa",
-3
View File
@@ -163,7 +163,6 @@
"Unshare" : "Lopeta jakaminen",
"Cannot copy, please copy the link manually" : "Kopioiminen ei onnistu. Kopioi linkki manuaalisesti",
"Copy internal link" : "Kopioi sisäinen linkki",
"For people who already have access" : "Henkilöille, joilla on jo käyttöoikeus",
"Internal link" : "Sisäinen linkki",
"Shared via link by {initiator}" : "Jaettu linkin kautta käyttäjältä {initiator}",
"File request ({label})" : "Tiedostopyyntö ({label})",
@@ -246,7 +245,6 @@
"Toggle list of others with access to this directory" : "Vaihda näkymää kansioon käyttöoikeuden omaavista käyttäjistä",
"Toggle list of others with access to this file" : "Vaihda näkymää tiedostoon käyttöoikeuden omaavista käyttäjistä",
"Shares" : "Jaot",
"Shares from apps or other sources which are not included in internal or external shares." : "Jaot muista sovelluksista tai lähteistä, jotka eivät sisälly sisäisiin tai ulkoisiin jakoihin.",
"Type names or teams" : "Kirjoita nimet tai tiimit",
"Type an email" : "Kirjoita sähköpostiosoite",
"Unable to load the shares list" : "Jakolistan haku epäonnistui",
@@ -255,7 +253,6 @@
"Shared with you by {owner}" : "{owner} jakoi tämän kanssasi",
"Internal shares" : "Sisäiset jaot",
"External shares" : "Ulkoiset jaot",
"Additional shares" : "Muut jaot",
"Link to a file" : "Linkki tiedostoon",
"_Accept share_::_Accept shares_" : ["Hyväksy jako","Hyväksy jaot"],
"Open in Files" : "Avaa tiedostosovelluksessa",
-17
View File
@@ -201,7 +201,6 @@ OC.L10N.register(
"Unshare" : "Delen stoppen",
"Cannot copy, please copy the link manually" : "Kan niet kopiëren, kopieer de link handmatig",
"Copy internal link" : "Kopieer interne link",
"For people who already have access" : "Voor personen die al toegang hebben",
"Internal link" : "Interne link",
"{shareWith} by {initiator}" : "{shareWith} door {initiator}",
"Shared via link by {initiator}" : "Gedeeld via link door {initiator}",
@@ -212,12 +211,9 @@ OC.L10N.register(
"Share link ({index})" : "Deellink ({index})",
"Create public link" : "Creëer openbare link",
"Actions for \"{title}\"" : "Acties voor \"{title}\"",
"Copy public link of \"{title}\"" : "Kopieer publieke link van \"{title}\"",
"Error, please enter proper password and/or expiration date" : "Fout. geef een geldig wachtwoord op en/of een vervaldatum",
"Link share created" : "Te delen share gemaakt",
"Error while creating the share" : "Fout bij maken share",
"Your browser does not support copying, please copy the link manually:" : "Je browser ondersteund geen kopiëren, kopieer de link handmatig",
"Successfully copied public link" : "De publieke link is succesvol gekopieerd",
"Please enter the following required information before creating the share" : "Geef de volgend verplichte gegevens op voor het aanmaken van de deellink",
"Password protection (enforced)" : "Wachtwoordbeveiliging (afgedwongen)",
"Password protection" : "Wachtwoordbeveiliging",
@@ -236,8 +232,6 @@ OC.L10N.register(
"Can edit" : "Kan bewerken",
"Custom permissions" : "Aangepaste machtigingen",
"Resharing is not allowed" : "Opnieuw delen niet toegestaan",
"Name or email …" : "Naam of e-mail …",
"Name, email, or Federated Cloud ID …" : "Naam, e-mail of gefedereerde cloud ID …",
"Searching …" : "Zoeken ...",
"No elements found." : "Geen elementen gevonden.",
"Search everywhere" : "Zoek in alles",
@@ -259,7 +253,6 @@ OC.L10N.register(
"Successfully uploaded files" : "Succesvol geüploade bestanden",
"View terms of service" : "Toon gebruiksvoorwaarden",
"Terms of service" : "Gebruiksvoorwaarden",
"Share with {user}" : "Deel met {user}",
"Share with email {email}" : "Deel met e-mail {email}",
"Share with group" : "Deel met groep",
"Share in conversation" : "Deel in gesprek",
@@ -304,14 +297,6 @@ OC.L10N.register(
"Unable to fetch inherited shares" : "Kon overerfde shares niet ophalen",
"Link shares" : "Deel shares",
"Shares" : "Shares",
"Share files within your organization. Recipients who can already view the file can also use this link for easy access." : "Deel bestanden in je organisatie. Ontvangers die het bestand al kunnen zien, kunnen deze link gebruiken voor makkelijke toegang.",
"Share files with others outside your organization via public links and email addresses. You can also share to {productName} accounts on other instances using their federated cloud ID." : "Deel bestanden met anderen buiten je organisatie via publieke links en e-mailadressen, Je kan ook delen naar{productName} accounts op andere instanties door gebruik te maken van hun gefedereerde cloud ID.",
"Shares from apps or other sources which are not included in internal or external shares." : "Shares van apps of andere bronnen welke niet zijn inbegrepen in interne of externe shares.",
"Type names, teams, federated cloud IDs" : "Type namen, teams of gefedereerde cloud ID's",
"Type names or teams" : "Type namen of teams",
"Type a federated cloud ID" : "Type een gefedereerde cloud ID",
"Type an email" : "Type een e-mail",
"Type an email or federated cloud ID" : "Type een e-mail of gefedereerde cloud ID",
"Unable to load the shares list" : "Kon de shares-lijst niet laden",
"Expires {relativetime}" : "Vervalt {relativetime}",
"this share just expired." : "deze share is net verlopen.",
@@ -330,9 +315,7 @@ OC.L10N.register(
"Shared" : "Gedeeld",
"Shared by {ownerDisplayName}" : "Gedeeld door {ownerDisplayName}",
"Shared multiple times with different people" : "Meerdere keren gedeeld met verschillende mensen",
"Sharing options" : "Deel opties",
"Shared with others" : "Gedeeld met anderen",
"You do not have enough permissions to share this file." : "Je hebt niet genoeg machtigingen om dit bestand te delen.",
"People" : "Mensen",
"Create file request" : "Maak bestandsaanvraag",
"Upload files to {foldername}" : "Upload bestanden naar {foldername}",
-17
View File
@@ -199,7 +199,6 @@
"Unshare" : "Delen stoppen",
"Cannot copy, please copy the link manually" : "Kan niet kopiëren, kopieer de link handmatig",
"Copy internal link" : "Kopieer interne link",
"For people who already have access" : "Voor personen die al toegang hebben",
"Internal link" : "Interne link",
"{shareWith} by {initiator}" : "{shareWith} door {initiator}",
"Shared via link by {initiator}" : "Gedeeld via link door {initiator}",
@@ -210,12 +209,9 @@
"Share link ({index})" : "Deellink ({index})",
"Create public link" : "Creëer openbare link",
"Actions for \"{title}\"" : "Acties voor \"{title}\"",
"Copy public link of \"{title}\"" : "Kopieer publieke link van \"{title}\"",
"Error, please enter proper password and/or expiration date" : "Fout. geef een geldig wachtwoord op en/of een vervaldatum",
"Link share created" : "Te delen share gemaakt",
"Error while creating the share" : "Fout bij maken share",
"Your browser does not support copying, please copy the link manually:" : "Je browser ondersteund geen kopiëren, kopieer de link handmatig",
"Successfully copied public link" : "De publieke link is succesvol gekopieerd",
"Please enter the following required information before creating the share" : "Geef de volgend verplichte gegevens op voor het aanmaken van de deellink",
"Password protection (enforced)" : "Wachtwoordbeveiliging (afgedwongen)",
"Password protection" : "Wachtwoordbeveiliging",
@@ -234,8 +230,6 @@
"Can edit" : "Kan bewerken",
"Custom permissions" : "Aangepaste machtigingen",
"Resharing is not allowed" : "Opnieuw delen niet toegestaan",
"Name or email …" : "Naam of e-mail …",
"Name, email, or Federated Cloud ID …" : "Naam, e-mail of gefedereerde cloud ID …",
"Searching …" : "Zoeken ...",
"No elements found." : "Geen elementen gevonden.",
"Search everywhere" : "Zoek in alles",
@@ -257,7 +251,6 @@
"Successfully uploaded files" : "Succesvol geüploade bestanden",
"View terms of service" : "Toon gebruiksvoorwaarden",
"Terms of service" : "Gebruiksvoorwaarden",
"Share with {user}" : "Deel met {user}",
"Share with email {email}" : "Deel met e-mail {email}",
"Share with group" : "Deel met groep",
"Share in conversation" : "Deel in gesprek",
@@ -302,14 +295,6 @@
"Unable to fetch inherited shares" : "Kon overerfde shares niet ophalen",
"Link shares" : "Deel shares",
"Shares" : "Shares",
"Share files within your organization. Recipients who can already view the file can also use this link for easy access." : "Deel bestanden in je organisatie. Ontvangers die het bestand al kunnen zien, kunnen deze link gebruiken voor makkelijke toegang.",
"Share files with others outside your organization via public links and email addresses. You can also share to {productName} accounts on other instances using their federated cloud ID." : "Deel bestanden met anderen buiten je organisatie via publieke links en e-mailadressen, Je kan ook delen naar{productName} accounts op andere instanties door gebruik te maken van hun gefedereerde cloud ID.",
"Shares from apps or other sources which are not included in internal or external shares." : "Shares van apps of andere bronnen welke niet zijn inbegrepen in interne of externe shares.",
"Type names, teams, federated cloud IDs" : "Type namen, teams of gefedereerde cloud ID's",
"Type names or teams" : "Type namen of teams",
"Type a federated cloud ID" : "Type een gefedereerde cloud ID",
"Type an email" : "Type een e-mail",
"Type an email or federated cloud ID" : "Type een e-mail of gefedereerde cloud ID",
"Unable to load the shares list" : "Kon de shares-lijst niet laden",
"Expires {relativetime}" : "Vervalt {relativetime}",
"this share just expired." : "deze share is net verlopen.",
@@ -328,9 +313,7 @@
"Shared" : "Gedeeld",
"Shared by {ownerDisplayName}" : "Gedeeld door {ownerDisplayName}",
"Shared multiple times with different people" : "Meerdere keren gedeeld met verschillende mensen",
"Sharing options" : "Deel opties",
"Shared with others" : "Gedeeld met anderen",
"You do not have enough permissions to share this file." : "Je hebt niet genoeg machtigingen om dit bestand te delen.",
"People" : "Mensen",
"Create file request" : "Maak bestandsaanvraag",
"Upload files to {foldername}" : "Upload bestanden naar {foldername}",
@@ -8,6 +8,7 @@
namespace OCA\Files_Sharing\AppInfo;
use OC\Group\DisplayNameCache as GroupDisplayNameCache;
use OC\Share\Share;
use OC\User\DisplayNameCache;
use OCA\Files\Event\LoadAdditionalScriptsEvent;
use OCA\Files\Event\LoadSidebar;
@@ -33,6 +34,8 @@ use OCA\Files_Sharing\Middleware\SharingCheckMiddleware;
use OCA\Files_Sharing\MountProvider;
use OCA\Files_Sharing\Notification\Listener;
use OCA\Files_Sharing\Notification\Notifier;
use OCA\Files_Sharing\ShareBackend\File;
use OCA\Files_Sharing\ShareBackend\Folder;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
@@ -49,7 +52,6 @@ use OCP\Group\Events\GroupChangedEvent;
use OCP\Group\Events\GroupDeletedEvent;
use OCP\Group\Events\UserAddedEvent;
use OCP\Group\Events\UserRemovedEvent;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\IGroup;
use OCP\Share\Events\BeforeShareDeletedEvent;
@@ -75,8 +77,7 @@ class Application extends App implements IBootstrap {
function () use ($c) {
return $c->get(Manager::class);
},
$c->get(ICloudIdManager::class),
$c->get(IConfig::class),
$c->get(ICloudIdManager::class)
);
});
@@ -129,6 +130,9 @@ class Application extends App implements IBootstrap {
$context->injectFn([$this, 'registerEventsScripts']);
Helper::registerHooks();
Share::registerBackend('file', File::class);
Share::registerBackend('folder', Folder::class, 'file');
}
@@ -7,6 +7,7 @@
*/
namespace OCA\Files_Sharing\Controller;
use OC\Security\CSP\ContentSecurityPolicy;
use OC\ServerNotAvailableException;
use OCA\DAV\Connector\Sabre\PublicAuth;
use OCA\FederatedFileSharing\FederatedShareProvider;
@@ -92,7 +93,15 @@ class ShareController extends AuthPublicShareController {
$this->eventDispatcher->dispatchTyped(new BeforeTemplateRenderedEvent($this->share, BeforeTemplateRenderedEvent::SCOPE_PUBLIC_SHARE_AUTH));
return new TemplateResponse('core', 'publicshareauth', $templateParameters, 'guest');
$response = new TemplateResponse('core', 'publicshareauth', $templateParameters, 'guest');
if ($this->share->getSendPasswordByTalk()) {
$csp = new ContentSecurityPolicy();
$csp->addAllowedConnectDomain('*');
$csp->addAllowedMediaDomain('blob:');
$response->setContentSecurityPolicy($csp);
}
return $response;
}
/**
@@ -103,7 +112,15 @@ class ShareController extends AuthPublicShareController {
$this->eventDispatcher->dispatchTyped(new BeforeTemplateRenderedEvent($this->share, BeforeTemplateRenderedEvent::SCOPE_PUBLIC_SHARE_AUTH));
return new TemplateResponse('core', 'publicshareauth', $templateParameters, 'guest');
$response = new TemplateResponse('core', 'publicshareauth', $templateParameters, 'guest');
if ($this->share->getSendPasswordByTalk()) {
$csp = new ContentSecurityPolicy();
$csp->addAllowedConnectDomain('*');
$csp->addAllowedMediaDomain('blob:');
$response->setContentSecurityPolicy($csp);
}
return $response;
}
/**
@@ -114,7 +131,15 @@ class ShareController extends AuthPublicShareController {
$this->eventDispatcher->dispatchTyped(new BeforeTemplateRenderedEvent($this->share, BeforeTemplateRenderedEvent::SCOPE_PUBLIC_SHARE_AUTH));
return new TemplateResponse('core', 'publicshareauth', $templateParameters, 'guest');
$response = new TemplateResponse('core', 'publicshareauth', $templateParameters, 'guest');
if ($this->share->getSendPasswordByTalk()) {
$csp = new ContentSecurityPolicy();
$csp->addAllowedConnectDomain('*');
$csp->addAllowedMediaDomain('blob:');
$response->setContentSecurityPolicy($csp);
}
return $response;
}
/**
@@ -128,11 +128,11 @@ class ShareesAPIController extends OCSController {
$shareTypes[] = IShare::TYPE_GROUP;
}
if ($this->isRemoteSharingAllowed()) {
if ($this->isRemoteSharingAllowed($itemType)) {
$shareTypes[] = IShare::TYPE_REMOTE;
}
if ($this->isRemoteGroupSharingAllowed()) {
if ($this->isRemoteGroupSharingAllowed($itemType)) {
$shareTypes[] = IShare::TYPE_REMOTE_GROUP;
}
@@ -309,11 +309,11 @@ class ShareesAPIController extends OCSController {
$shareTypes[] = IShare::TYPE_GROUP;
}
if ($this->isRemoteSharingAllowed()) {
if ($this->isRemoteSharingAllowed($itemType)) {
$shareTypes[] = IShare::TYPE_REMOTE;
}
if ($this->isRemoteGroupSharingAllowed()) {
if ($this->isRemoteGroupSharingAllowed($itemType)) {
$shareTypes[] = IShare::TYPE_REMOTE_GROUP;
}
@@ -353,12 +353,24 @@ class ShareesAPIController extends OCSController {
* @param string $itemType
* @return bool
*/
protected function isRemoteSharingAllowed(): bool {
return $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
protected function isRemoteSharingAllowed(string $itemType): bool {
try {
// FIXME: static foo makes unit testing unnecessarily difficult
$backend = Share::getBackend($itemType);
return $backend->isShareTypeAllowed(IShare::TYPE_REMOTE);
} catch (\Exception $e) {
return false;
}
}
protected function isRemoteGroupSharingAllowed(): bool {
return $this->federatedShareProvider->isOutgoingServer2serverGroupShareEnabled();
protected function isRemoteGroupSharingAllowed(string $itemType): bool {
try {
// FIXME: static foo makes unit testing unnecessarily difficult
$backend = Share::getBackend($itemType);
return $backend->isShareTypeAllowed(IShare::TYPE_REMOTE_GROUP);
} catch (\Exception $e) {
return false;
}
}
-3
View File
@@ -26,7 +26,6 @@ use OCP\Files\NotPermittedException;
use OCP\Files\Storage\IStorageFactory;
use OCP\Http\Client\IClientService;
use OCP\ICertificateManager;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\IGroup;
use OCP\IGroupManager;
@@ -57,7 +56,6 @@ class Manager {
private ISetupManager $setupManager,
private ICertificateManager $certificateManager,
private ExternalShareMapper $externalShareMapper,
private IConfig $config,
) {
$this->user = $userSession->getUser();
}
@@ -115,7 +113,6 @@ class Manager {
'password' => $externalShare->getPassword(),
'mountpoint' => $externalShare->getMountpoint(),
'owner' => $externalShare->getOwner(),
'verify' => !$this->config->getSystemValueBool('sharing.federation.allowSelfSignedCertificates'),
];
return $this->mountShare($options, $user);
}
-3
View File
@@ -17,7 +17,6 @@ use OCP\Files\Config\IPartialMountProvider;
use OCP\Files\Storage\IStorageFactory;
use OCP\Http\Client\IClientService;
use OCP\ICertificateManager;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\IUser;
use OCP\Server;
@@ -38,7 +37,6 @@ class MountProvider implements IMountProvider, IPartialMountProvider {
private readonly IDBConnection $connection,
callable $managerProvider,
private readonly ICloudIdManager $cloudIdManager,
private IConfig $config,
) {
$this->managerProvider = $managerProvider;
}
@@ -52,7 +50,6 @@ class MountProvider implements IMountProvider, IPartialMountProvider {
$data['cloudId'] = $this->cloudIdManager->getCloudId($data['owner'], $data['remote']);
$data['certificateManager'] = Server::get(ICertificateManager::class);
$data['HttpClientService'] = Server::get(IClientService::class);
$data['verify'] = !$this->config->getSystemValueBool('sharing.federation.allowSelfSignedCertificates');
return new Mount(self::STORAGE, $mountPoint, $data, $manager, $storageFactory);
}
+2 -9
View File
@@ -30,15 +30,13 @@ use OCP\Files\StorageInvalidException;
use OCP\Files\StorageNotAvailableException;
use OCP\Http\Client\IClientService;
use OCP\Http\Client\LocalServerException;
use OCP\IAppConfig;
use OCP\ICacheFactory;
use OCP\IConfig;
use OCP\IUserSession;
use OCP\OCM\Exceptions\OCMArgumentException;
use OCP\OCM\Exceptions\OCMProviderException;
use OCP\OCM\IOCMDiscoveryService;
use OCP\Server;
use OCP\Share\IManager as IShareManager;
use OCP\Util;
use Psr\Log\LoggerInterface;
class Storage extends DAV implements ISharedStorage, IDisableEncryptionStorage, IReliableEtagStorage {
@@ -50,8 +48,6 @@ class Storage extends DAV implements ISharedStorage, IDisableEncryptionStorage,
private bool $updateChecked = false;
private ExternalShareManager $manager;
private IConfig $config;
private IAppConfig $appConfig;
private IShareManager $shareManager;
/**
* @param array{HttpClientService: IClientService, manager: ExternalShareManager, cloudId: ICloudId, mountpoint: string, token: string, password: ?string}|array $options
@@ -64,8 +60,6 @@ class Storage extends DAV implements ISharedStorage, IDisableEncryptionStorage,
$this->logger = Server::get(LoggerInterface::class);
$discoveryService = Server::get(IOCMDiscoveryService::class);
$this->config = Server::get(IConfig::class);
$this->appConfig = Server::get(IAppConfig::class);
$this->shareManager = Server::get(IShareManager::class);
// use default path to webdav if not found on discovery
try {
@@ -336,8 +330,7 @@ class Storage extends DAV implements ISharedStorage, IDisableEncryptionStorage,
}
public function isSharable(string $path): bool {
if ($this->shareManager->sharingDisabledForUser(Server::get(IUserSession::class)->getUser()?->getUID())
|| !$this->appConfig->getValueBool('core', 'shareapi_allow_resharing', true)) {
if (Util::isSharingDisabledForUser() || !Share::isResharingAllowed()) {
return false;
}
return (bool)($this->getPermissions($path) & Constants::PERMISSION_SHARE);
+10 -1
View File
@@ -29,7 +29,7 @@ class Helper {
* @param View $view
* @return string $path
*/
public static function generateUniqueTarget(string $path, View $view): string {
public static function generateUniqueTarget($path, $view) {
$pathinfo = pathinfo($path);
$ext = isset($pathinfo['extension']) ? '.' . $pathinfo['extension'] : '';
$name = $pathinfo['filename'];
@@ -82,4 +82,13 @@ class Helper {
return $shareFolder;
}
/**
* set default share folder
*
* @param string $shareFolder
*/
public static function setShareFolder($shareFolder) {
Server::get(IConfig::class)->setSystemValue('share_folder', $shareFolder);
}
}
@@ -0,0 +1,228 @@
<?php
/**
* SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Files_Sharing\ShareBackend;
use OC\Files\Filesystem;
use OC\Files\View;
use OCA\FederatedFileSharing\FederatedShareProvider;
use OCA\Files_Sharing\Helper;
use OCP\Files\NotFoundException;
use OCP\IDBConnection;
use OCP\Server;
use OCP\Share\IShare;
use OCP\Share_Backend_File_Dependent;
use Psr\Log\LoggerInterface;
class File implements Share_Backend_File_Dependent {
public const FORMAT_SHARED_STORAGE = 0;
public const FORMAT_GET_FOLDER_CONTENTS = 1;
public const FORMAT_FILE_APP_ROOT = 2;
public const FORMAT_OPENDIR = 3;
public const FORMAT_GET_ALL = 4;
public const FORMAT_PERMISSIONS = 5;
public const FORMAT_TARGET_NAMES = 6;
private $path;
public function __construct(
private ?FederatedShareProvider $federatedShareProvider = null,
) {
if ($federatedShareProvider) {
$this->federatedShareProvider = $federatedShareProvider;
} else {
$this->federatedShareProvider = Server::get(FederatedShareProvider::class);
}
}
public function isValidSource($itemSource, $uidOwner) {
try {
$path = Filesystem::getPath($itemSource);
// FIXME: attributes should not be set here,
// keeping this pattern for now to avoid unexpected
// regressions
$this->path = Filesystem::normalizePath(basename($path));
return true;
} catch (NotFoundException $e) {
return false;
}
}
public function getFilePath($itemSource, $uidOwner) {
if (isset($this->path)) {
$path = $this->path;
$this->path = null;
return $path;
} else {
try {
$path = Filesystem::getPath($itemSource);
return $path;
} catch (NotFoundException $e) {
return false;
}
}
}
/**
* create unique target
*
* @param string $itemSource
* @param string $shareWith
* @return string
*/
public function generateTarget($itemSource, $shareWith) {
$shareFolder = Helper::getShareFolder();
$target = Filesystem::normalizePath($shareFolder . '/' . basename($itemSource));
Filesystem::initMountPoints($shareWith);
$view = new View('/' . $shareWith . '/files');
if (!$view->is_dir($shareFolder)) {
$dir = '';
$subdirs = explode('/', $shareFolder);
foreach ($subdirs as $subdir) {
$dir = $dir . '/' . $subdir;
if (!$view->is_dir($dir)) {
$view->mkdir($dir);
}
}
}
return Helper::generateUniqueTarget($target, $view);
}
public function formatItems($items, $format, $parameters = null) {
if ($format === self::FORMAT_SHARED_STORAGE) {
// Only 1 item should come through for this format call
$item = array_shift($items);
return [
'parent' => $item['parent'],
'path' => $item['path'],
'storage' => $item['storage'],
'permissions' => $item['permissions'],
'uid_owner' => $item['uid_owner'],
];
} elseif ($format === self::FORMAT_GET_FOLDER_CONTENTS) {
$files = [];
foreach ($items as $item) {
$file = [];
$file['fileid'] = $item['file_source'];
$file['storage'] = $item['storage'];
$file['path'] = $item['file_target'];
$file['parent'] = $item['file_parent'];
$file['name'] = basename($item['file_target']);
$file['mimetype'] = $item['mimetype'];
$file['mimepart'] = $item['mimepart'];
$file['mtime'] = $item['mtime'];
$file['encrypted'] = $item['encrypted'];
$file['etag'] = $item['etag'];
$file['uid_owner'] = $item['uid_owner'];
$file['displayname_owner'] = $item['displayname_owner'];
$storage = Filesystem::getStorage('/');
$cache = $storage->getCache();
$file['size'] = $item['size'];
$files[] = $file;
}
return $files;
} elseif ($format === self::FORMAT_OPENDIR) {
$files = [];
foreach ($items as $item) {
$files[] = basename($item['file_target']);
}
return $files;
} elseif ($format === self::FORMAT_GET_ALL) {
$ids = [];
foreach ($items as $item) {
$ids[] = $item['file_source'];
}
return $ids;
} elseif ($format === self::FORMAT_PERMISSIONS) {
$filePermissions = [];
foreach ($items as $item) {
$filePermissions[$item['file_source']] = $item['permissions'];
}
return $filePermissions;
} elseif ($format === self::FORMAT_TARGET_NAMES) {
$targets = [];
foreach ($items as $item) {
$targets[] = $item['file_target'];
}
return $targets;
}
return [];
}
/**
* check if server2server share is enabled
*
* @param int $shareType
* @return boolean
*/
public function isShareTypeAllowed($shareType) {
if ($shareType === IShare::TYPE_REMOTE) {
return $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
}
if ($shareType === IShare::TYPE_REMOTE_GROUP) {
return $this->federatedShareProvider->isOutgoingServer2serverGroupShareEnabled();
}
return true;
}
/**
* resolve reshares to return the correct source item
* @param array $source
* @return array source item
*/
protected static function resolveReshares($source) {
if (isset($source['parent'])) {
$parent = $source['parent'];
while (isset($parent)) {
$qb = Server::get(IDBConnection::class)->getQueryBuilder();
$qb->select('parent', 'uid_owner')
->from('share')
->where(
$qb->expr()->eq('id', $qb->createNamedParameter($parent))
);
$result = $qb->executeQuery();
$item = $result->fetchAssociative();
$result->closeCursor();
if (isset($item['parent'])) {
$parent = $item['parent'];
} else {
$fileOwner = $item['uid_owner'];
break;
}
}
} else {
$fileOwner = $source['uid_owner'];
}
if (isset($fileOwner)) {
$source['fileOwner'] = $fileOwner;
} else {
Server::get(LoggerInterface::class)->error('No owner found for reshare', ['app' => 'files_sharing']);
}
return $source;
}
/**
* @param string $target
* @param array $share
* @return array|false source item
*/
public static function getSource($target, $share) {
if ($share['item_type'] === 'folder' && $target !== '') {
// note: in case of ext storage mount points the path might be empty
// which would cause a leading slash to appear
$share['path'] = ltrim($share['path'] . '/' . $target, '/');
}
return self::resolveReshares($share);
}
}
@@ -0,0 +1,61 @@
<?php
/**
* SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Files_Sharing\ShareBackend;
use OCP\IDBConnection;
use OCP\Server;
use OCP\Share_Backend_Collection;
class Folder extends File implements Share_Backend_Collection {
public function getChildren($itemSource): array {
$children = [];
$parents = [$itemSource];
$qb = Server::get(IDBConnection::class)->getQueryBuilder();
$qb->select('id')
->from('mimetypes')
->where(
$qb->expr()->eq('mimetype', $qb->createNamedParameter('httpd/unix-directory'))
);
$result = $qb->executeQuery();
if (($row = $result->fetchAssociative()) !== false) {
$mimetype = (int)$row['id'];
} else {
$mimetype = -1;
}
$result->closeCursor();
while (!empty($parents)) {
$qb = Server::get(IDBConnection::class)->getQueryBuilder();
$parents = array_map(function ($parent) use ($qb) {
return $qb->createNamedParameter($parent);
}, $parents);
$qb->select('`fileid', 'name', '`mimetype')
->from('filecache')
->where(
$qb->expr()->in('parent', $parents)
);
$result = $qb->executeQuery();
$parents = [];
foreach ($result->iterateAssociative() as $file) {
$children[] = ['source' => $file['fileid'], 'file_path' => $file['name']];
// If a child folder is found look inside it
if ((int)$file['mimetype'] === $mimetype) {
$parents[] = $file['fileid'];
}
}
$result->closeCursor();
}
return $children;
}
}
+1 -9
View File
@@ -36,11 +36,8 @@ use OCP\Files\Storage\IDisableEncryptionStorage;
use OCP\Files\Storage\ILockingStorage;
use OCP\Files\Storage\ISharedStorage;
use OCP\Files\Storage\IStorage;
use OCP\IAppConfig;
use OCP\IUserSession;
use OCP\Lock\ILockingProvider;
use OCP\Server;
use OCP\Share\IManager as IShareManager;
use OCP\Share\IShare;
use OCP\Util;
use Override;
@@ -85,16 +82,12 @@ class SharedStorage extends Jail implements LegacyISharedStorage, ISharedStorage
private $ownerUserFolder = null;
private string $sourcePath = '';
private IAppConfig $appConfig;
private IShareManager $shareManager;
private static int $initDepth = 0;
public function __construct(array $parameters) {
$this->ownerView = $parameters['ownerView'];
$this->logger = Server::get(LoggerInterface::class);
$this->appConfig = Server::get(IAppConfig::class);
$this->shareManager = Server::get(IShareManager::class);
$this->superShare = $parameters['superShare'];
$this->groupedShares = $parameters['groupedShares'];
@@ -286,8 +279,7 @@ class SharedStorage extends Jail implements LegacyISharedStorage, ISharedStorage
}
public function isSharable(string $path): bool {
if ($this->shareManager->sharingDisabledForUser(Server::get(IUserSession::class)->getUser()?->getUID())
|| !$this->appConfig->getValueBool('core', 'shareapi_allow_resharing', true)) {
if (Util::isSharingDisabledForUser() || !Share::isResharingAllowed()) {
return false;
}
return (bool)($this->getPermissions($path) & Constants::PERMISSION_SHARE);
+8 -8
View File
@@ -230,14 +230,14 @@ class CacheTest extends TestCase {
[
[
'name' => 'shareddir',
'path' => '/' . self::TEST_FILES_SHARING_API_USER2 . '/files/shareddir',
'path' => 'files/shareddir',
'mimetype' => 'httpd/unix-directory',
'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
'displayname_owner' => 'User One',
],
[
'name' => 'shared single file.txt',
'path' => '/' . self::TEST_FILES_SHARING_API_USER2 . '/files/shared single file.txt',
'path' => 'files/shared single file.txt',
'mimetype' => 'text/plain',
'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
'displayname_owner' => 'User One',
@@ -254,21 +254,21 @@ class CacheTest extends TestCase {
[
[
'name' => 'bar.txt',
'path' => '/' . self::TEST_FILES_SHARING_API_USER2 . '/files/shareddir/bar.txt',
'path' => 'bar.txt',
'mimetype' => 'text/plain',
'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
'displayname_owner' => 'User One',
],
[
'name' => 'emptydir',
'path' => '/' . self::TEST_FILES_SHARING_API_USER2 . '/files/shareddir/emptydir',
'path' => 'emptydir',
'mimetype' => 'httpd/unix-directory',
'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
'displayname_owner' => 'User One',
],
[
'name' => 'subdir',
'path' => '/' . self::TEST_FILES_SHARING_API_USER2 . '/files/shareddir/subdir',
'path' => 'subdir',
'mimetype' => 'httpd/unix-directory',
'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
'displayname_owner' => 'User One',
@@ -336,21 +336,21 @@ class CacheTest extends TestCase {
[
[
'name' => 'another too.txt',
'path' => '/' . self::TEST_FILES_SHARING_API_USER3 . '/files/subdir/another too.txt',
'path' => 'another too.txt',
'mimetype' => 'text/plain',
'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
'displayname_owner' => 'User One',
],
[
'name' => 'another.txt',
'path' => '/' . self::TEST_FILES_SHARING_API_USER3 . '/files/subdir/another.txt',
'path' => 'another.txt',
'mimetype' => 'text/plain',
'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
'displayname_owner' => 'User One',
],
[
'name' => 'not a text file.xml',
'path' => '/' . self::TEST_FILES_SHARING_API_USER3 . '/files/subdir/not a text file.xml',
'path' => 'not a text file.xml',
'mimetype' => 'application/xml',
'uid_owner' => self::TEST_FILES_SHARING_API_USER1,
'displayname_owner' => 'User One',
@@ -282,11 +282,13 @@ class ShareesAPIControllerTest extends TestCase {
$sharees->expects($this->any())
->method('isRemoteSharingAllowed')
->with($itemType)
->willReturn($remoteSharingEnabled);
$sharees->expects($this->any())
->method('isRemoteGroupSharingAllowed')
->with($itemType)
->willReturn($isRemoteGroupSharingEnabled);
$this->shareManager->expects($this->any())
@@ -383,6 +385,25 @@ class ShareesAPIControllerTest extends TestCase {
}
}
public static function dataIsRemoteSharingAllowed() {
return [
['file', true],
['folder', true],
['', false],
['contacts', false],
];
}
/**
*
* @param string $itemType
* @param bool $expected
*/
#[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'dataIsRemoteSharingAllowed')]
public function testIsRemoteSharingAllowed($itemType, $expected): void {
$this->assertSame($expected, $this->invokePrivate($this->sharees, 'isRemoteSharingAllowed', [$itemType]));
}
public function testSearchSharingDisabled(): void {
$this->shareManager->expects($this->once())
->method('sharingDisabledForUser')
+1 -5
View File
@@ -30,7 +30,6 @@ use OCP\Http\Client\IClientService;
use OCP\Http\Client\IResponse;
use OCP\ICacheFactory;
use OCP\ICertificateManager;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\IGroup;
use OCP\IGroupManager;
@@ -72,7 +71,6 @@ class ManagerTest extends TestCase {
protected ISetupManager&MockObject $setupManager;
protected ICertificateManager&MockObject $certificateManager;
private ExternalShareMapper $externalShareMapper;
private IConfig $config;
protected function setUp(): void {
parent::setUp();
@@ -83,7 +81,6 @@ class ManagerTest extends TestCase {
->disableOriginalConstructor()->getMock();
$this->cloudFederationProviderManager = $this->createMock(ICloudFederationProviderManager::class);
$this->cloudFederationFactory = $this->createMock(ICloudFederationFactory::class);
$this->config = $this->createMock(IConfig::class);
$this->groupManager = $this->createMock(IGroupManager::class);
$this->userManager = $this->createMock(IUserManager::class);
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
@@ -122,7 +119,7 @@ class ManagerTest extends TestCase {
$this->contactsManager,
$this->createMock(IURLGenerator::class),
$this->userManager,
), $this->config);
));
$this->group1 = $this->createMock(IGroup::class);
$this->group1->expects($this->any())->method('getGID')->willReturn('group1');
@@ -172,7 +169,6 @@ class ManagerTest extends TestCase {
$this->setupManager,
$this->certificateManager,
$this->externalShareMapper,
$this->config,
]
)->onlyMethods(['tryOCMEndPoint'])->getMock();
}
@@ -13,15 +13,13 @@ use OCA\Files_Sharing\External\Storage;
use OCP\Http\Client\IClient;
use OCP\Http\Client\IClientService;
use OCP\Http\Client\IResponse;
use OCP\ICertificateManager;
use OCP\Server;
/**
* Tests for the external Storage class for remote shares.
*/
#[\PHPUnit\Framework\Attributes\Group(name: 'DB')]
class ExternalStorageTest extends \Test\TestCase {
public static function optionsProvider(): array {
public static function optionsProvider() {
return [
[
'http://remoteserver:8080/owncloud',
@@ -56,7 +54,7 @@ class ExternalStorageTest extends \Test\TestCase {
}
private function getTestStorage($uri) {
$certificateManager = Server::get(ICertificateManager::class);
$certificateManager = \OC::$server->getCertificateManager();
$httpClientService = $this->createMock(IClientService::class);
$manager = $this->createMock(ExternalShareManager::class);
$client = $this->createMock(IClient::class);
+36
View File
@@ -0,0 +1,36 @@
<?php
/**
* SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Files_Sharing\Tests;
use OC\Files\Filesystem;
use OCA\Files_Sharing\Helper;
use OCP\IConfig;
use OCP\Server;
/**
* Class HelperTest
*/
#[\PHPUnit\Framework\Attributes\Group(name: 'DB')]
class HelperTest extends TestCase {
/**
* test set and get share folder
*/
public function testSetGetShareFolder(): void {
$this->assertSame('/', Helper::getShareFolder());
Helper::setShareFolder('/Shared/Folder');
$sharedFolder = Helper::getShareFolder();
$this->assertSame('/Shared/Folder', Helper::getShareFolder());
$this->assertTrue(Filesystem::is_dir($sharedFolder));
// cleanup
Server::get(IConfig::class)->deleteSystemValue('share_folder');
}
}
+2 -1
View File
@@ -9,6 +9,7 @@ namespace OCA\Files_Sharing\Tests;
use OC\Files\FileInfo;
use OC\Files\Filesystem;
use OCA\Files_Sharing\Helper;
use OCP\Constants;
use OCP\IConfig;
use OCP\IGroupManager;
@@ -127,7 +128,7 @@ class ShareTest extends TestCase {
Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE | Constants::PERMISSION_SHARE
);
Server::get(IConfig::class)->setSystemValue('share_folder', '/Shared/subfolder');
Helper::setShareFolder('/Shared/subfolder');
$share = $this->share(
IShare::TYPE_USER,
+1 -1
View File
@@ -4,7 +4,7 @@ OC.L10N.register(
"Profile" : "Profil",
"This application provides the profile" : "Denne applikation leverer profilen",
"Provides a customisable user profile interface." : "Leverer en brugerdefinerbar brugerprofil grænseflade.",
"Searching …" : "Søger …",
"Searching …" : "Søger ...",
"Not found" : "Ikke fundet",
"Insert" : "Indsæt",
"You have not added any info yet" : "Du har ikke tilføjet nogen information endnu",
+1 -1
View File
@@ -2,7 +2,7 @@
"Profile" : "Profil",
"This application provides the profile" : "Denne applikation leverer profilen",
"Provides a customisable user profile interface." : "Leverer en brugerdefinerbar brugerprofil grænseflade.",
"Searching …" : "Søger …",
"Searching …" : "Søger ...",
"Not found" : "Ikke fundet",
"Insert" : "Indsæt",
"You have not added any info yet" : "Du har ikke tilføjet nogen information endnu",
-4
View File
@@ -1,15 +1,11 @@
OC.L10N.register(
"profile",
{
"Profile picker" : "Profilväljare",
"Profile" : "Profil",
"This application provides the profile" : "Denna app tillhandahåller profilen",
"Provides a customisable user profile interface." : "Tillhandahåller ett anpassningsbart gränssnitt för användarprofiler.",
"Searching …" : "Söker …",
"Not found" : "Hittades inte",
"Search for a user profile" : "Sök efter en användarprofil",
"Search for a user profile. Start typing" : "Sök efter en användarprofil. Börja skriva",
"Insert selected user profile link" : "Infoga vald länk till användarprofil",
"Insert" : "Infoga",
"You have not added any info yet" : "Du har inte angivit någon information ännu",
"{user} has not added any info yet" : "{user} har inte angivit någon information ännu",
-4
View File
@@ -1,13 +1,9 @@
{ "translations": {
"Profile picker" : "Profilväljare",
"Profile" : "Profil",
"This application provides the profile" : "Denna app tillhandahåller profilen",
"Provides a customisable user profile interface." : "Tillhandahåller ett anpassningsbart gränssnitt för användarprofiler.",
"Searching …" : "Söker …",
"Not found" : "Hittades inte",
"Search for a user profile" : "Sök efter en användarprofil",
"Search for a user profile. Start typing" : "Sök efter en användarprofil. Börja skriva",
"Insert selected user profile link" : "Infoga vald länk till användarprofil",
"Insert" : "Infoga",
"You have not added any info yet" : "Du har inte angivit någon information ännu",
"{user} has not added any info yet" : "{user} har inte angivit någon information ännu",
+14 -46
View File
@@ -35,7 +35,6 @@ OC.L10N.register(
"Could not remove app." : "Kon app niet verwijderen",
"Could not update app." : "Kon app niet updaten",
"One time login" : "Eenmalige inlog",
"QR Code login" : "QR Code login",
"Wrong password" : "Onjuist wachtwoord",
"Unable to change personal password" : "Kan persoonlijk wachtwoord niet wijzigen",
"Saved" : "Opgeslagen",
@@ -53,7 +52,7 @@ OC.L10N.register(
"Email setting test" : "E-mailinstellingen test",
"Well done, %s!" : "Goed gedaan, %s!",
"If you received this email, the email configuration seems to be correct." : "Als je deze e-mail hebt ontvangen, dan lijken de e-mailinstellingen correct.",
"Email could not be sent. Check your mail server log" : "Er kon geen e-mail verstuurd worden. Controleer je mailserver log files",
"Email could not be sent. Check your mail server log" : "Er kon geen e-mail verstuurd worden. Controleer je server log files",
"A problem occurred while sending the email. Please revise your settings. (Error: %s)" : "Er ontstond een probleem bij het versturen van de e-mail. Controleer je instellingen. (Fout: %s)",
"You need to set your account email before being able to send test emails. Go to %s for that." : "Je moet je e-mail voor je account instellen voordat je e-mail kan versturen. Ga hiervoor naar %s.",
"Recently active" : "Recent actief",
@@ -63,27 +62,27 @@ OC.L10N.register(
"Settings saved" : "Instellingen opgeslagen",
"Unable to change full name" : "Kan de volledige naam niet wijzigen",
"Unable to change email address" : "Kan e-mailadres niet wijzigen",
"Unable to set invalid phone number" : "Kan geen ongeldig telefoonnummer instellen",
"Unable to set invalid phone number" : "Kon geen geldig telefoonnummer instellen",
"Unable to set invalid website" : "Kan geen ongeldig website instellen",
"Some account data was invalid" : "Sommige accountgegevens waren ongeldig",
"Some account data was invalid" : "Sommige accountgegevens ongeldig",
"In order to verify your Twitter account, post the following tweet on Twitter (please make sure to post it without any line breaks):" : "Om je Twitter-account te verifiëren moet je de volgende tweet op Twitter plaatsen (zorg dat je het plaatst zonder regelafbreking):",
"In order to verify your Website, store the following content in your web-root at '.well-known/CloudIdVerificationCode.txt' (please make sure that the complete text is in one line):" : "Om je website te verifiëren voeg de inhoud toe binnen de web-root van je server '.well-known/CloudIdVerificationCode.txt' (zorg dat de tekst op één regel staat):",
"%1$s changed your password on %2$s." : "%1$s wijzigde je wachtwoord op %2$s.",
"%1$s changed your password on %2$s." : "%1$swijzigde je wachtwoord op %2$s.",
"Your password on %s was changed." : "Je wachtwoord op %s is gewijzigd.",
"Your password on %s was reset by an administrator." : "Je wachtwoord op %s werd hersteld door een beheerder.",
"Your password on %s was reset." : "Je wachtwoord op %s is opnieuw ingesteld",
"Password for %1$s changed on %2$s" : "Wachtwoord voor %1$s gewijzigd op %2$s",
"Password for %1$s changed on %2$s" : "Wachtwoord voor %1$s gewijzigd op %2$s",
"Password changed for %s" : "Wachtwoord gewijzigd voor %s",
"If you did not request this, please contact an administrator." : "Als je dat niet aanvroeg, neem dan contact op met een beheerder.",
"Your email address on %s was changed." : "Je e-mailadres op %sis gewijzigd.",
"Your email address on %s was changed by an administrator." : "Je e-mailadres op %s is gewijzigd door een beheerder.",
"Email address for %1$s changed on %2$s" : "E-mailadres voor %1$s gewijzigd op %2$s",
"Email address changed for %s" : "E-mailadres gewijzigd voor %s",
"The new email address is %s" : "Het nieuwe e-mailadres is %s",
"The new email address is %s" : "Het nieuwe e-mailadres is %s",
"Your %s account was created" : "Je %s account is aangemaakt",
"Welcome aboard" : "Welkom aan boord",
"Welcome aboard %s" : "Welkom aan boord %s",
"Welcome to your %s account, you can add, protect, and share your data." : "Welkom bij je %s account; je kunt nu je data toevoegen, beschermen en delen.",
"Welcome to your %s account, you can add, protect, and share your data." : "Welkom bij je %s account; je kunt nu je bestanden toevoegen en veilig delen.",
"Your Login is: %s" : "Je login is: %s",
"Set your password" : "Stel je wachtwoord in",
"Go to %s" : "Ga naar %s",
@@ -95,10 +94,9 @@ OC.L10N.register(
"Users" : "Gebruikers",
"Additional settings" : "Aanvullende instellingen",
"Assistant" : "Assistent",
"Administration privileges" : "Beheerdersmachtigingen",
"Administration privileges" : "Beheerdersprivileges",
"Groupware" : "Groupware",
"Overview" : "Overzicht",
"Quick presets" : "Snelle voorkeuren",
"Basic settings" : "Basis-instellingen",
"Sharing" : "Delen",
"Availability" : "Beschikbaarheid",
@@ -106,7 +104,6 @@ OC.L10N.register(
"Personal info" : "Persoonlijke info",
"Mobile & desktop" : "Mobiel & desktop",
"Artificial Intelligence" : "Artificiële Intelligentie",
"None / STARTTLS" : "None / STARTTLS",
"Email server" : "E-mailserver",
"Mail Providers" : "Mail-providers",
"Mail provider enables sending emails directly through the user's personal email account. At present, this functionality is limited to calendar invitations. It requires Nextcloud Mail 4.1 and an email account in Nextcloud Mail that matches the user's email address in Nextcloud." : "Mailprovider maakt het mogelijk e-mails rechtstreeks via het persoonlijke e-mailaccount van de gebruiker te verzenden. Momenteel is deze functionaliteit beperkt tot agenda-uitnodigingen. Het vereist Nextcloud Mail 4.1 en een e-mailaccount in Nextcloud Mail dat overeenkomt met het e-mailadres van de gebruiker in Nextcloud.",
@@ -114,23 +111,22 @@ OC.L10N.register(
"User's email account" : "E-mailaccount gebruiker",
"System email account" : "E-mailaccount systeem",
"Security & setup checks" : "Veiligheids- en instellingencontrole",
"Settings presets" : "Instellingen voorkeuren",
"Background jobs" : "Achtergrondtaken",
"Unlimited" : "Ongelimiteerd",
"Verifying" : "Controleren",
"Verifying …" : "Controleren...",
"Verify" : "Controleer",
"Verifying" : "Controleer",
"Verifying …" : "Verifiëren...",
"Verify" : "Verifiëren",
"Allowed admin IP ranges" : "Toegestane beheerder IP-reeksen",
"Admin IP filtering isn't applied." : "Beheerder IP-filtering wordt niet toegepast.",
"Admin IP filtering isn't applied." : "Admin IP-filtering wordt niet toegepast.",
"Configuration key \"%1$s\" expects an array (%2$s found). Admin IP range validation will not be applied." : "Configuratiesleutel \"%1$s\" verwacht een array (%2$s gevonden). Validatie van beheerder IP-bereik wordt niet toegepast.",
"Configuration key \"%1$s\" contains invalid IP range(s): \"%2$s\"" : "Configuratiesleutel \"%1$s\" bevat ongeldig(e) IP-bereik(en): \"%2$s\"",
"Admin IP filtering is correctly configured." : "Beheerder IP-filtering is juist geconfigureerd.",
"App directories owner" : "Eigenaar app mappen",
"Some app directories are owned by a different user than the web server one. This may be the case if apps have been installed manually. Check the permissions of the following app directories:\n%s" : "Sommige app mappen zijn eigendom van een andere gebruiker dan op de webserver. Dat kan het geval zijn als apps handmatig zijn geïnstalleerd. Controleer de machtigingen van de volgende app mappen:\n%s",
"Some app directories are owned by a different user than the web server one. This may be the case if apps have been installed manually. Check the permissions of the following app directories:\n%s" : "Sommige app mappen zijn eigendom van een andere gebruiker dan op de webserver . Dat kan het geval zijn als apps handmatig zijn geïnstalleerd. Controleer de machtigingen van de volgende app mappen:\n%s",
"App directories have the correct owner \"%s\"" : "App mappen hebben de juiste eigenaar \"%s\"",
"Brute-force Throttle" : "Bruteforce begrenzing",
"Your remote address could not be determined." : "Je remote adres kon niet bepaald worden",
"Your remote address was identified as \"%s\" and is brute-force throttled at the moment slowing down the performance of various requests. If the remote address is not your address this can be an indication that a proxy is not configured correctly." : "Je remote adres is geregistreerd als \"%s\" en wordt op dit moment afgeremd ter bescherming tegen bruteforce aanvallen. Dit verlaagt de prestaties van verschillende aanvragen. Als het remote adres niet uw adres is kan dit wijzen op een verkeerd ingestelde proxy. ",
"Your remote address was identified as \"%s\" and is brute-force throttled at the moment slowing down the performance of various requests. If the remote address is not your address this can be an indication that a proxy is not configured correctly." : "Je remote adres is geregistreerd als \"%s\" en wordt op dit moment afgeremd ter bescherming van bruteforce aanvallen. Dit verlaagt de performantie van verschillende aanvragen. Als het remote adres niet uw adres is kan dit wijzen op een verkeerd ingestelde proxy. ",
"Your remote address \"%s\" is not brute-force throttled." : "Je remote adres %s is niet bruteforce begrensd.",
"Old administration imported certificates" : "Oude administratie geïmporteerde certificaten",
"A background job is pending that checks for administration imported SSL certificates. Please check back later." : "Er is een achtergrondtaak in behandeling die controleert op het beheer van geïmporteerde SSL-certificaten. Kom later nog eens terug.",
@@ -139,8 +135,6 @@ OC.L10N.register(
"Integrity checker has been disabled. Integrity cannot be verified." : "Integriteitscontrole is uitgeschakeld. Integriteit kan niet gecontroleerd worden.",
"No altered files" : "Geen gewijzigde bestanden",
"Some files have not passed the integrity check. {link1} {link2}" : "Sommige bestanden zijn niet door de integriteitscontrole gekomen. {link1} {link2}",
"List of invalid files…" : "Lijst van ongeldige bestanden...",
"Rescan…" : "Herscannen...",
"Cron errors" : "Cron fouten",
"It was not possible to execute the cron job via CLI. The following technical errors have appeared:\n%s" : "Het was niet mogelijk om de systeem cron via CLI uit te voeren. De volgende technische problemen traden op:\n%s",
"The last cron job ran without errors." : "De laatste crontaak liep zonder fouten.",
@@ -170,7 +164,6 @@ OC.L10N.register(
"Email test" : "E-mail test",
"Email test was successfully sent" : "Test e-mail is succesvol verzonden",
"You have not set or verified your email server configuration, yet. Please head over to the \"Basic settings\" in order to set them. Afterwards, use the \"Send email\" button below the form to verify your settings." : "U heeft uw emailserverconfiguratie nog niet ingesteld of geverifieerd. Navigeer alstublieft naar de Standaardinstellingen om deze in te stellen. Hierna kunt u de \"Stuur email\" knop onder dit formulier gebruiken om uw instellingen te verifiëren",
"Your IP address was resolved as %s" : "Jouw IP adres is herleid naar %s",
"HTTPS access and URLs" : "HTTPS toegang en URL's",
"Accessing site insecurely via HTTP. You are strongly advised to set up your server to require HTTPS instead. Without it some important web functionality like \"copy to clipboard\" or \"service workers\" will not work!" : "Connectie via HTTP. U wordt aangeraden uw server in te stellen om het gebruik van HTTPS af te dwingen. Zonder HTTPS zullen functies zoals \"kopieer naar klembord\" en \"service workers\" niet werken.",
"Accessing site insecurely via HTTP." : "Site wordt onveiligd benaderd via HTTP.",
@@ -186,8 +179,6 @@ OC.L10N.register(
"The old server-side-encryption format is enabled. We recommend disabling this." : "Het oude server-side-encryptie formaat is ingeschakeld. We raden aan om dit uit te schakelen.",
"The logging level is set to debug level. Use debug level only when you have a problem to diagnose, and then reset your log level to a less-verbose level as it outputs a lot of information, and can affect your server performance." : "Het logniveau is ingesteld op foutopsporingsniveau. Gebruik het foutopsporingsniveau alleen om een probleem te diagnosticeren, en reset vervolgens uw log-niveau naar een niveau met minder informatie, omdat het veel informatie oplevert en de prestaties van uw server kan beïnvloeden.",
"Server has no maintenance window start time configured. This means resource intensive daily background jobs will also be executed during your main usage time. We recommend to set it to a time of low usage, so users are less impacted by the load caused from these heavy tasks." : "De server heeft geen onderhoudsvenster starttijd geconfigureerd. Dit betekent dat bron intensieve dagelijkse achtergrond taken ook worden uitgevoerd tijdens normaal gebruik. We adviseren om een tijdstip te kiezen met beperkt gebruik, zodat gebruikers minder worden beïnvloedt door de belasting gegenereerd door deze zware taken.",
"Memcache" : "Memcache",
"Configured" : "Geconfigureerd",
"The PHP function \"set_time_limit\" is not available. This could result in scripts being halted mid-execution, breaking your installation. Enabling this function is strongly recommended." : "De PHP functie \"set_time_limit\" is niet beschikbaar. Dit kan erin resulteren dat de scripts halverwege stoppen, waardoor de installatie ontregeld raakt. We adviseren sterk om deze functie in te schakelen.",
"Supported" : "Ondersteund",
"Your PHP does not have FreeType support, resulting in breakage of profile pictures and the settings interface." : "Je PHP heeft geen FreeType ondersteuning. Dit zal leiden tot verminkte profielafbeeldingen en instellingeninterface.",
@@ -198,21 +189,11 @@ OC.L10N.register(
"The shared memory based OPcache is disabled. For better performance, it is recommended to apply \"opcache.file_cache_only=0\" to your PHP configuration and use the file cache as second level cache only." : "De shared memory based OPcache is uitgeschakeld. Voor betere prestaties wordt aanbevolen om \"opcache.file_cache_only=0\" toe te passen in je PHP-configuratie en de bestandscache alleen te gebruiken als second level cache.",
"OPcache is not working as it should, opcache_get_status() returns false, please check configuration." : "OPcache werkt niet zoals zou moeten, opcache_get_status() retourneert false, controleer de configuratie.",
"PHP version" : "PHP versie",
"Valid enterprise license" : "Geldige enterprise licentie",
"Free push service" : "Gratis push dienst",
"Secure" : "Beveiligd",
"The read-only config has been enabled. This prevents setting some configurations via the web-interface. Furthermore, the file needs to be made writable manually for every update." : "De alleen-lezen config is ingeschakeld. Dit voorkomt het via de webinterface wijzigen van verschillende instellingen. Bovendien moet het bestand voor elke aanpassing handmatig op beschrijfbaar worden ingesteld.",
"Database version" : "Database versie",
"Unknown database platform" : "Onbekend database platform",
"Architecture" : "Architectuur",
"64-bit" : "64-bit",
"It seems like you are running a 32-bit PHP version. Nextcloud needs 64-bit to run well. Please upgrade your OS and PHP to 64-bit!" : "Het lijkt er op dat je een 32-bit versie van PHP gebruikt. Nextcloud heeft de 64-bit versie nodig om goed te werken. Voer een upgrade uit van je OS en PHP naar 64-bit.",
"_No scheduled tasks in the last day._::_No scheduled tasks in the last %n days._" : ["Geen geplande taken de afgelopen dag.","Geen geplande taken in de afgelopen %n dagen."],
"Temporary space available" : "Tijdelijke ruimte beschikbaar",
"Your database does not run with \"READ COMMITTED\" transaction isolation level. This can cause problems when multiple actions are executed in parallel." : "Je database draait niet met \"READ COMMITTED\" transactie-isolatie niveau. Dit kan problemen opleveren als er meerdere acties tegelijkertijd worden uitgevoerd.",
"Second factor configuration" : "Twee factor configuratie",
"This instance has no second factor provider available." : "Deze instantie heeft geen twee factor provider beschikbaar.",
"Font file loading" : "Font bestand laden",
"Profile information" : "Profiel informatie",
"Profile picture, full name, email, phone number, address, website, Twitter, organisation, role, headline, biography, and whether your profile is enabled" : "Profielfoto, volledige naam, e-mailadres, telefoonnummer, adres, website, Twitter, organisatie, rol, kop, biografie en of je profiel is ingeschakeld",
"Nextcloud settings" : "Nextcloud instellingen",
@@ -274,9 +255,7 @@ OC.L10N.register(
"This app is supported via your current Nextcloud subscription." : "Deze app wordt ondersteund via je huidige Nextcloud abonnement.",
"Featured apps are developed by and within the community. They offer central functionality and are ready for production use." : "Aanbevolen apps worden ontwikkeld door en binnen de community. Ze bieden centrale functionaliteit en zijn klaar voor productie.",
"Community rating: {score}/5" : "Gemeenschapsscore: {score}/5",
"installed" : "Geïnstalleerd",
"Learn more" : "Meer weten",
"Disable office suites" : "Schakel Office-suites uit",
"Disable all" : "Alles uitschakelen",
"Download and enable all" : "Download en alles inschakelen",
"All apps are up-to-date." : "Alle apps zijn up-to-date.",
@@ -381,8 +360,6 @@ OC.L10N.register(
"AJAX" : "AJAX",
"Webcron" : "Webcron",
"Profile" : "Profiel",
"Enable the profile picker" : "Schakel de profiel kiezer in",
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "In- en uit-schakelen van de profiel kiezer in de Slimme Kiezer en de profiel link voorbeelden.",
"Password confirmation is required" : "Wachtwoordbevestiging vereist",
"Server-side encryption" : "Server-side versleuteling",
"Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "Server-side versleuteling maakt het mogelijk om bestanden te versleutelen die worden geüploaded. Dit betekent wel enig prestatieverlies, dus schakel het alleen in als het nodig is.",
@@ -625,12 +602,10 @@ OC.L10N.register(
"Pronouns" : "Persoonlijke voornaamwoorden",
"Role" : "Rol",
"X (formerly Twitter)" : "X (voorheen Twitter)",
"Bluesky" : "Bluesky",
"Website" : "Website",
"Profile visibility" : "Profiel zichtbaarheid",
"Locale" : "Regionale instellingen",
"First day of week" : "Eerste dag van de week",
"timezone" : "tijdzone",
"Private" : "Privé",
"Only visible to people matched via phone number integration through Talk on mobile" : "Alleen zichtbaar voor mensen die via telefoonnummerintegratie gematcht zijn voor Talk op mobiel",
"Not available as this property is required for core functionality including file sharing and calendar invitations" : "Niet beschikbaar omdat deze eigenschap benodigd is voor de basisfunctionaliteit inclusief bestandsdeling en kalender uitnodigingen",
@@ -648,11 +623,6 @@ OC.L10N.register(
"App bundles" : "App bundels",
"Featured apps" : "Aanbevolen apps",
"Supported apps" : "Ondersteunde apps",
"Open source" : "Open source",
"Good performance" : "Goede prestatie",
"Best performance" : "Beste prestatie",
"Limited ODF compatibility" : "Gelimiteerde ODF compatibiliteit",
"Best Microsoft compatibility" : "Beste Microsoft compatibiliteit",
"Show to everyone" : "Laat zien aan iedereen",
"Show to logged in accounts only" : "Laat alleen zien aan ingelogde accounts",
"Hide" : "Verbergen",
@@ -713,10 +683,8 @@ OC.L10N.register(
"Email sent" : "E-mail verzonden",
"{progress}% Deploying …" : "{progress} % implementeren ...",
"{progress}% Initializing …" : "{progress} % initialiseren ...",
"None/STARTTLS" : "None/STARTTLS",
"SSL" : "SSL",
"Credentials" : "Inloggegevens",
"SMTP Login" : "SMTP Login",
"SMTP Password" : "SMTP wachtwoord",
"Save" : "Bewaar",
"Test and verify email settings" : "Test en controleer de e-mailinstellingen"
+14 -46
View File
@@ -33,7 +33,6 @@
"Could not remove app." : "Kon app niet verwijderen",
"Could not update app." : "Kon app niet updaten",
"One time login" : "Eenmalige inlog",
"QR Code login" : "QR Code login",
"Wrong password" : "Onjuist wachtwoord",
"Unable to change personal password" : "Kan persoonlijk wachtwoord niet wijzigen",
"Saved" : "Opgeslagen",
@@ -51,7 +50,7 @@
"Email setting test" : "E-mailinstellingen test",
"Well done, %s!" : "Goed gedaan, %s!",
"If you received this email, the email configuration seems to be correct." : "Als je deze e-mail hebt ontvangen, dan lijken de e-mailinstellingen correct.",
"Email could not be sent. Check your mail server log" : "Er kon geen e-mail verstuurd worden. Controleer je mailserver log files",
"Email could not be sent. Check your mail server log" : "Er kon geen e-mail verstuurd worden. Controleer je server log files",
"A problem occurred while sending the email. Please revise your settings. (Error: %s)" : "Er ontstond een probleem bij het versturen van de e-mail. Controleer je instellingen. (Fout: %s)",
"You need to set your account email before being able to send test emails. Go to %s for that." : "Je moet je e-mail voor je account instellen voordat je e-mail kan versturen. Ga hiervoor naar %s.",
"Recently active" : "Recent actief",
@@ -61,27 +60,27 @@
"Settings saved" : "Instellingen opgeslagen",
"Unable to change full name" : "Kan de volledige naam niet wijzigen",
"Unable to change email address" : "Kan e-mailadres niet wijzigen",
"Unable to set invalid phone number" : "Kan geen ongeldig telefoonnummer instellen",
"Unable to set invalid phone number" : "Kon geen geldig telefoonnummer instellen",
"Unable to set invalid website" : "Kan geen ongeldig website instellen",
"Some account data was invalid" : "Sommige accountgegevens waren ongeldig",
"Some account data was invalid" : "Sommige accountgegevens ongeldig",
"In order to verify your Twitter account, post the following tweet on Twitter (please make sure to post it without any line breaks):" : "Om je Twitter-account te verifiëren moet je de volgende tweet op Twitter plaatsen (zorg dat je het plaatst zonder regelafbreking):",
"In order to verify your Website, store the following content in your web-root at '.well-known/CloudIdVerificationCode.txt' (please make sure that the complete text is in one line):" : "Om je website te verifiëren voeg de inhoud toe binnen de web-root van je server '.well-known/CloudIdVerificationCode.txt' (zorg dat de tekst op één regel staat):",
"%1$s changed your password on %2$s." : "%1$s wijzigde je wachtwoord op %2$s.",
"%1$s changed your password on %2$s." : "%1$swijzigde je wachtwoord op %2$s.",
"Your password on %s was changed." : "Je wachtwoord op %s is gewijzigd.",
"Your password on %s was reset by an administrator." : "Je wachtwoord op %s werd hersteld door een beheerder.",
"Your password on %s was reset." : "Je wachtwoord op %s is opnieuw ingesteld",
"Password for %1$s changed on %2$s" : "Wachtwoord voor %1$s gewijzigd op %2$s",
"Password for %1$s changed on %2$s" : "Wachtwoord voor %1$s gewijzigd op %2$s",
"Password changed for %s" : "Wachtwoord gewijzigd voor %s",
"If you did not request this, please contact an administrator." : "Als je dat niet aanvroeg, neem dan contact op met een beheerder.",
"Your email address on %s was changed." : "Je e-mailadres op %sis gewijzigd.",
"Your email address on %s was changed by an administrator." : "Je e-mailadres op %s is gewijzigd door een beheerder.",
"Email address for %1$s changed on %2$s" : "E-mailadres voor %1$s gewijzigd op %2$s",
"Email address changed for %s" : "E-mailadres gewijzigd voor %s",
"The new email address is %s" : "Het nieuwe e-mailadres is %s",
"The new email address is %s" : "Het nieuwe e-mailadres is %s",
"Your %s account was created" : "Je %s account is aangemaakt",
"Welcome aboard" : "Welkom aan boord",
"Welcome aboard %s" : "Welkom aan boord %s",
"Welcome to your %s account, you can add, protect, and share your data." : "Welkom bij je %s account; je kunt nu je data toevoegen, beschermen en delen.",
"Welcome to your %s account, you can add, protect, and share your data." : "Welkom bij je %s account; je kunt nu je bestanden toevoegen en veilig delen.",
"Your Login is: %s" : "Je login is: %s",
"Set your password" : "Stel je wachtwoord in",
"Go to %s" : "Ga naar %s",
@@ -93,10 +92,9 @@
"Users" : "Gebruikers",
"Additional settings" : "Aanvullende instellingen",
"Assistant" : "Assistent",
"Administration privileges" : "Beheerdersmachtigingen",
"Administration privileges" : "Beheerdersprivileges",
"Groupware" : "Groupware",
"Overview" : "Overzicht",
"Quick presets" : "Snelle voorkeuren",
"Basic settings" : "Basis-instellingen",
"Sharing" : "Delen",
"Availability" : "Beschikbaarheid",
@@ -104,7 +102,6 @@
"Personal info" : "Persoonlijke info",
"Mobile & desktop" : "Mobiel & desktop",
"Artificial Intelligence" : "Artificiële Intelligentie",
"None / STARTTLS" : "None / STARTTLS",
"Email server" : "E-mailserver",
"Mail Providers" : "Mail-providers",
"Mail provider enables sending emails directly through the user's personal email account. At present, this functionality is limited to calendar invitations. It requires Nextcloud Mail 4.1 and an email account in Nextcloud Mail that matches the user's email address in Nextcloud." : "Mailprovider maakt het mogelijk e-mails rechtstreeks via het persoonlijke e-mailaccount van de gebruiker te verzenden. Momenteel is deze functionaliteit beperkt tot agenda-uitnodigingen. Het vereist Nextcloud Mail 4.1 en een e-mailaccount in Nextcloud Mail dat overeenkomt met het e-mailadres van de gebruiker in Nextcloud.",
@@ -112,23 +109,22 @@
"User's email account" : "E-mailaccount gebruiker",
"System email account" : "E-mailaccount systeem",
"Security & setup checks" : "Veiligheids- en instellingencontrole",
"Settings presets" : "Instellingen voorkeuren",
"Background jobs" : "Achtergrondtaken",
"Unlimited" : "Ongelimiteerd",
"Verifying" : "Controleren",
"Verifying …" : "Controleren...",
"Verify" : "Controleer",
"Verifying" : "Controleer",
"Verifying …" : "Verifiëren...",
"Verify" : "Verifiëren",
"Allowed admin IP ranges" : "Toegestane beheerder IP-reeksen",
"Admin IP filtering isn't applied." : "Beheerder IP-filtering wordt niet toegepast.",
"Admin IP filtering isn't applied." : "Admin IP-filtering wordt niet toegepast.",
"Configuration key \"%1$s\" expects an array (%2$s found). Admin IP range validation will not be applied." : "Configuratiesleutel \"%1$s\" verwacht een array (%2$s gevonden). Validatie van beheerder IP-bereik wordt niet toegepast.",
"Configuration key \"%1$s\" contains invalid IP range(s): \"%2$s\"" : "Configuratiesleutel \"%1$s\" bevat ongeldig(e) IP-bereik(en): \"%2$s\"",
"Admin IP filtering is correctly configured." : "Beheerder IP-filtering is juist geconfigureerd.",
"App directories owner" : "Eigenaar app mappen",
"Some app directories are owned by a different user than the web server one. This may be the case if apps have been installed manually. Check the permissions of the following app directories:\n%s" : "Sommige app mappen zijn eigendom van een andere gebruiker dan op de webserver. Dat kan het geval zijn als apps handmatig zijn geïnstalleerd. Controleer de machtigingen van de volgende app mappen:\n%s",
"Some app directories are owned by a different user than the web server one. This may be the case if apps have been installed manually. Check the permissions of the following app directories:\n%s" : "Sommige app mappen zijn eigendom van een andere gebruiker dan op de webserver . Dat kan het geval zijn als apps handmatig zijn geïnstalleerd. Controleer de machtigingen van de volgende app mappen:\n%s",
"App directories have the correct owner \"%s\"" : "App mappen hebben de juiste eigenaar \"%s\"",
"Brute-force Throttle" : "Bruteforce begrenzing",
"Your remote address could not be determined." : "Je remote adres kon niet bepaald worden",
"Your remote address was identified as \"%s\" and is brute-force throttled at the moment slowing down the performance of various requests. If the remote address is not your address this can be an indication that a proxy is not configured correctly." : "Je remote adres is geregistreerd als \"%s\" en wordt op dit moment afgeremd ter bescherming tegen bruteforce aanvallen. Dit verlaagt de prestaties van verschillende aanvragen. Als het remote adres niet uw adres is kan dit wijzen op een verkeerd ingestelde proxy. ",
"Your remote address was identified as \"%s\" and is brute-force throttled at the moment slowing down the performance of various requests. If the remote address is not your address this can be an indication that a proxy is not configured correctly." : "Je remote adres is geregistreerd als \"%s\" en wordt op dit moment afgeremd ter bescherming van bruteforce aanvallen. Dit verlaagt de performantie van verschillende aanvragen. Als het remote adres niet uw adres is kan dit wijzen op een verkeerd ingestelde proxy. ",
"Your remote address \"%s\" is not brute-force throttled." : "Je remote adres %s is niet bruteforce begrensd.",
"Old administration imported certificates" : "Oude administratie geïmporteerde certificaten",
"A background job is pending that checks for administration imported SSL certificates. Please check back later." : "Er is een achtergrondtaak in behandeling die controleert op het beheer van geïmporteerde SSL-certificaten. Kom later nog eens terug.",
@@ -137,8 +133,6 @@
"Integrity checker has been disabled. Integrity cannot be verified." : "Integriteitscontrole is uitgeschakeld. Integriteit kan niet gecontroleerd worden.",
"No altered files" : "Geen gewijzigde bestanden",
"Some files have not passed the integrity check. {link1} {link2}" : "Sommige bestanden zijn niet door de integriteitscontrole gekomen. {link1} {link2}",
"List of invalid files…" : "Lijst van ongeldige bestanden...",
"Rescan…" : "Herscannen...",
"Cron errors" : "Cron fouten",
"It was not possible to execute the cron job via CLI. The following technical errors have appeared:\n%s" : "Het was niet mogelijk om de systeem cron via CLI uit te voeren. De volgende technische problemen traden op:\n%s",
"The last cron job ran without errors." : "De laatste crontaak liep zonder fouten.",
@@ -168,7 +162,6 @@
"Email test" : "E-mail test",
"Email test was successfully sent" : "Test e-mail is succesvol verzonden",
"You have not set or verified your email server configuration, yet. Please head over to the \"Basic settings\" in order to set them. Afterwards, use the \"Send email\" button below the form to verify your settings." : "U heeft uw emailserverconfiguratie nog niet ingesteld of geverifieerd. Navigeer alstublieft naar de Standaardinstellingen om deze in te stellen. Hierna kunt u de \"Stuur email\" knop onder dit formulier gebruiken om uw instellingen te verifiëren",
"Your IP address was resolved as %s" : "Jouw IP adres is herleid naar %s",
"HTTPS access and URLs" : "HTTPS toegang en URL's",
"Accessing site insecurely via HTTP. You are strongly advised to set up your server to require HTTPS instead. Without it some important web functionality like \"copy to clipboard\" or \"service workers\" will not work!" : "Connectie via HTTP. U wordt aangeraden uw server in te stellen om het gebruik van HTTPS af te dwingen. Zonder HTTPS zullen functies zoals \"kopieer naar klembord\" en \"service workers\" niet werken.",
"Accessing site insecurely via HTTP." : "Site wordt onveiligd benaderd via HTTP.",
@@ -184,8 +177,6 @@
"The old server-side-encryption format is enabled. We recommend disabling this." : "Het oude server-side-encryptie formaat is ingeschakeld. We raden aan om dit uit te schakelen.",
"The logging level is set to debug level. Use debug level only when you have a problem to diagnose, and then reset your log level to a less-verbose level as it outputs a lot of information, and can affect your server performance." : "Het logniveau is ingesteld op foutopsporingsniveau. Gebruik het foutopsporingsniveau alleen om een probleem te diagnosticeren, en reset vervolgens uw log-niveau naar een niveau met minder informatie, omdat het veel informatie oplevert en de prestaties van uw server kan beïnvloeden.",
"Server has no maintenance window start time configured. This means resource intensive daily background jobs will also be executed during your main usage time. We recommend to set it to a time of low usage, so users are less impacted by the load caused from these heavy tasks." : "De server heeft geen onderhoudsvenster starttijd geconfigureerd. Dit betekent dat bron intensieve dagelijkse achtergrond taken ook worden uitgevoerd tijdens normaal gebruik. We adviseren om een tijdstip te kiezen met beperkt gebruik, zodat gebruikers minder worden beïnvloedt door de belasting gegenereerd door deze zware taken.",
"Memcache" : "Memcache",
"Configured" : "Geconfigureerd",
"The PHP function \"set_time_limit\" is not available. This could result in scripts being halted mid-execution, breaking your installation. Enabling this function is strongly recommended." : "De PHP functie \"set_time_limit\" is niet beschikbaar. Dit kan erin resulteren dat de scripts halverwege stoppen, waardoor de installatie ontregeld raakt. We adviseren sterk om deze functie in te schakelen.",
"Supported" : "Ondersteund",
"Your PHP does not have FreeType support, resulting in breakage of profile pictures and the settings interface." : "Je PHP heeft geen FreeType ondersteuning. Dit zal leiden tot verminkte profielafbeeldingen en instellingeninterface.",
@@ -196,21 +187,11 @@
"The shared memory based OPcache is disabled. For better performance, it is recommended to apply \"opcache.file_cache_only=0\" to your PHP configuration and use the file cache as second level cache only." : "De shared memory based OPcache is uitgeschakeld. Voor betere prestaties wordt aanbevolen om \"opcache.file_cache_only=0\" toe te passen in je PHP-configuratie en de bestandscache alleen te gebruiken als second level cache.",
"OPcache is not working as it should, opcache_get_status() returns false, please check configuration." : "OPcache werkt niet zoals zou moeten, opcache_get_status() retourneert false, controleer de configuratie.",
"PHP version" : "PHP versie",
"Valid enterprise license" : "Geldige enterprise licentie",
"Free push service" : "Gratis push dienst",
"Secure" : "Beveiligd",
"The read-only config has been enabled. This prevents setting some configurations via the web-interface. Furthermore, the file needs to be made writable manually for every update." : "De alleen-lezen config is ingeschakeld. Dit voorkomt het via de webinterface wijzigen van verschillende instellingen. Bovendien moet het bestand voor elke aanpassing handmatig op beschrijfbaar worden ingesteld.",
"Database version" : "Database versie",
"Unknown database platform" : "Onbekend database platform",
"Architecture" : "Architectuur",
"64-bit" : "64-bit",
"It seems like you are running a 32-bit PHP version. Nextcloud needs 64-bit to run well. Please upgrade your OS and PHP to 64-bit!" : "Het lijkt er op dat je een 32-bit versie van PHP gebruikt. Nextcloud heeft de 64-bit versie nodig om goed te werken. Voer een upgrade uit van je OS en PHP naar 64-bit.",
"_No scheduled tasks in the last day._::_No scheduled tasks in the last %n days._" : ["Geen geplande taken de afgelopen dag.","Geen geplande taken in de afgelopen %n dagen."],
"Temporary space available" : "Tijdelijke ruimte beschikbaar",
"Your database does not run with \"READ COMMITTED\" transaction isolation level. This can cause problems when multiple actions are executed in parallel." : "Je database draait niet met \"READ COMMITTED\" transactie-isolatie niveau. Dit kan problemen opleveren als er meerdere acties tegelijkertijd worden uitgevoerd.",
"Second factor configuration" : "Twee factor configuratie",
"This instance has no second factor provider available." : "Deze instantie heeft geen twee factor provider beschikbaar.",
"Font file loading" : "Font bestand laden",
"Profile information" : "Profiel informatie",
"Profile picture, full name, email, phone number, address, website, Twitter, organisation, role, headline, biography, and whether your profile is enabled" : "Profielfoto, volledige naam, e-mailadres, telefoonnummer, adres, website, Twitter, organisatie, rol, kop, biografie en of je profiel is ingeschakeld",
"Nextcloud settings" : "Nextcloud instellingen",
@@ -272,9 +253,7 @@
"This app is supported via your current Nextcloud subscription." : "Deze app wordt ondersteund via je huidige Nextcloud abonnement.",
"Featured apps are developed by and within the community. They offer central functionality and are ready for production use." : "Aanbevolen apps worden ontwikkeld door en binnen de community. Ze bieden centrale functionaliteit en zijn klaar voor productie.",
"Community rating: {score}/5" : "Gemeenschapsscore: {score}/5",
"installed" : "Geïnstalleerd",
"Learn more" : "Meer weten",
"Disable office suites" : "Schakel Office-suites uit",
"Disable all" : "Alles uitschakelen",
"Download and enable all" : "Download en alles inschakelen",
"All apps are up-to-date." : "Alle apps zijn up-to-date.",
@@ -379,8 +358,6 @@
"AJAX" : "AJAX",
"Webcron" : "Webcron",
"Profile" : "Profiel",
"Enable the profile picker" : "Schakel de profiel kiezer in",
"Enable or disable the profile picker in the Smart Picker and the profile link previews." : "In- en uit-schakelen van de profiel kiezer in de Slimme Kiezer en de profiel link voorbeelden.",
"Password confirmation is required" : "Wachtwoordbevestiging vereist",
"Server-side encryption" : "Server-side versleuteling",
"Server-side encryption makes it possible to encrypt files which are uploaded to this server. This comes with limitations like a performance penalty, so enable this only if needed." : "Server-side versleuteling maakt het mogelijk om bestanden te versleutelen die worden geüploaded. Dit betekent wel enig prestatieverlies, dus schakel het alleen in als het nodig is.",
@@ -623,12 +600,10 @@
"Pronouns" : "Persoonlijke voornaamwoorden",
"Role" : "Rol",
"X (formerly Twitter)" : "X (voorheen Twitter)",
"Bluesky" : "Bluesky",
"Website" : "Website",
"Profile visibility" : "Profiel zichtbaarheid",
"Locale" : "Regionale instellingen",
"First day of week" : "Eerste dag van de week",
"timezone" : "tijdzone",
"Private" : "Privé",
"Only visible to people matched via phone number integration through Talk on mobile" : "Alleen zichtbaar voor mensen die via telefoonnummerintegratie gematcht zijn voor Talk op mobiel",
"Not available as this property is required for core functionality including file sharing and calendar invitations" : "Niet beschikbaar omdat deze eigenschap benodigd is voor de basisfunctionaliteit inclusief bestandsdeling en kalender uitnodigingen",
@@ -646,11 +621,6 @@
"App bundles" : "App bundels",
"Featured apps" : "Aanbevolen apps",
"Supported apps" : "Ondersteunde apps",
"Open source" : "Open source",
"Good performance" : "Goede prestatie",
"Best performance" : "Beste prestatie",
"Limited ODF compatibility" : "Gelimiteerde ODF compatibiliteit",
"Best Microsoft compatibility" : "Beste Microsoft compatibiliteit",
"Show to everyone" : "Laat zien aan iedereen",
"Show to logged in accounts only" : "Laat alleen zien aan ingelogde accounts",
"Hide" : "Verbergen",
@@ -711,10 +681,8 @@
"Email sent" : "E-mail verzonden",
"{progress}% Deploying …" : "{progress} % implementeren ...",
"{progress}% Initializing …" : "{progress} % initialiseren ...",
"None/STARTTLS" : "None/STARTTLS",
"SSL" : "SSL",
"Credentials" : "Inloggegevens",
"SMTP Login" : "SMTP Login",
"SMTP Password" : "SMTP wachtwoord",
"Save" : "Bewaar",
"Test and verify email settings" : "Test en controleer de e-mailinstellingen"
+3 -5
View File
@@ -30,9 +30,7 @@ use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\IAppConfig;
use OCP\IGroupManager;
use OCP\IUserManager;
use OCP\Settings\Events\DeclarativeSettingsGetValueEvent;
use OCP\Settings\Events\DeclarativeSettingsRegisterFormEvent;
use OCP\Settings\Events\DeclarativeSettingsSetValueEvent;
@@ -69,9 +67,9 @@ class Application extends App implements IBootstrap {
public function boot(IBootContext $context): void {
$server = $context->getServerContainer();
$config = $server->get(IAppConfig::class);
if ($config->getValueBool(self::APP_ID, 'enable_alt_user_backend')) {
$userManager = $server->get(IUserManager::class);
$config = $server->getConfig();
if ($config->getAppValue(self::APP_ID, 'enable_alt_user_backend', 'no') === 'yes') {
$userManager = $server->getUserManager();
// replace all user backends with this one
$userManager->clearBackends();
-1
View File
@@ -109,7 +109,6 @@ OC.L10N.register(
"Reset primary color" : "Återställ primär färg",
"Reset to default" : "Återställ till grundinställningar",
"Non image file selected" : "Vald fil är inte en bildfil",
"Failed to upload image" : "Det gick inte att ladda upp bilden",
"Preview of the selected image" : "Förhandsgranskning av den valda bilden",
"Universal access is very important to us. We follow web standards and check to make everything usable also without mouse, and assistive software such as screenreaders. We aim to be compliant with the {linkstart}Web Content Accessibility Guidelines{linkend} 2.1 on AA level, with the high contrast theme even on AAA level." : "Tillgänglighet är mycket viktig för oss. Vi följer webbstandarder och kontrollerar att allt är användbart även utan mus och hjälpmedel som skärmläsare. Vi strävar efter att följa {linkstart}Web Content Accessibility Guidelines{linkend} 2.1 på AA-nivå, med högkontrast-temat även på AAA-nivå.",
"If you find any issues, do not hesitate to report them on {issuetracker}our issue tracker{linkend}. And if you want to get involved, come join {designteam}our design team{linkend}!" : "Om du hittar några problem, tveka inte att rapportera dem på {issuetracker}vår problemhanterare{linkend}. Och om du vill engagera dig, gå med i {designteam}vårt designteam{linkend}!",
-1
View File
@@ -107,7 +107,6 @@
"Reset primary color" : "Återställ primär färg",
"Reset to default" : "Återställ till grundinställningar",
"Non image file selected" : "Vald fil är inte en bildfil",
"Failed to upload image" : "Det gick inte att ladda upp bilden",
"Preview of the selected image" : "Förhandsgranskning av den valda bilden",
"Universal access is very important to us. We follow web standards and check to make everything usable also without mouse, and assistive software such as screenreaders. We aim to be compliant with the {linkstart}Web Content Accessibility Guidelines{linkend} 2.1 on AA level, with the high contrast theme even on AAA level." : "Tillgänglighet är mycket viktig för oss. Vi följer webbstandarder och kontrollerar att allt är användbart även utan mus och hjälpmedel som skärmläsare. Vi strävar efter att följa {linkstart}Web Content Accessibility Guidelines{linkend} 2.1 på AA-nivå, med högkontrast-temat även på AAA-nivå.",
"If you find any issues, do not hesitate to report them on {issuetracker}our issue tracker{linkend}. And if you want to get involved, come join {designteam}our design team{linkend}!" : "Om du hittar några problem, tveka inte att rapportera dem på {issuetracker}vår problemhanterare{linkend}. Och om du vill engagera dig, gå med i {designteam}vårt designteam{linkend}!",
+1 -1
View File
@@ -30,7 +30,7 @@ OC.L10N.register(
"Appearance and accessibility" : "外观和辅助功能",
"PHP Imagick module" : "PHP Imagick 模块",
"The PHP module \"imagick\" is not enabled although the theming app is. For favicon generation to work correctly, you need to install and enable this module." : "PHP 模块“imagick”没有被启用,尽管已启用了主题程序。为了使收藏图标正常生成,您需要安装并启用这个模块。",
"The PHP module \"imagick\" in this instance has no SVG support. For better compatibility it is recommended to install it." : "此实例中的 PHP 模块 \"imagick\" 不支持 SVG。为了更好的兼容性,建议安装此模块。",
"The PHP module \"imagick\" in this instance has no SVG support. For better compatibility it is recommended to install it." : "此实例中的 PHP 模块 \"imagick\" 不支持 SVG。为了更好的兼容性,简易安装此模块。",
"Dark theme with high contrast mode" : "高对比度深色主题",
"Enable dark high contrast mode" : "使用高对比度深色模式",
"Similar to the high contrast mode, but with dark colours." : "类似高对比度模式,但是使用深色色调。",
+1 -1
View File
@@ -28,7 +28,7 @@
"Appearance and accessibility" : "外观和辅助功能",
"PHP Imagick module" : "PHP Imagick 模块",
"The PHP module \"imagick\" is not enabled although the theming app is. For favicon generation to work correctly, you need to install and enable this module." : "PHP 模块“imagick”没有被启用,尽管已启用了主题程序。为了使收藏图标正常生成,您需要安装并启用这个模块。",
"The PHP module \"imagick\" in this instance has no SVG support. For better compatibility it is recommended to install it." : "此实例中的 PHP 模块 \"imagick\" 不支持 SVG。为了更好的兼容性,建议安装此模块。",
"The PHP module \"imagick\" in this instance has no SVG support. For better compatibility it is recommended to install it." : "此实例中的 PHP 模块 \"imagick\" 不支持 SVG。为了更好的兼容性,简易安装此模块。",
"Dark theme with high contrast mode" : "高对比度深色主题",
"Enable dark high contrast mode" : "使用高对比度深色模式",
"Similar to the high contrast mode, but with dark colours." : "类似高对比度模式,但是使用深色色调。",
+2 -1
View File
@@ -6,6 +6,7 @@
*/
namespace OCA\Theming;
use OC\Kernel\Kernel;
use OCA\Theming\AppInfo\Application;
use OCA\Theming\Service\BackgroundService;
use OCP\App\AppPathNotFoundException;
@@ -395,7 +396,7 @@ class ThemingDefaults extends \OC_Defaults {
}
$route = $this->urlGenerator->linkToRoute('theming.Theming.getManifest', ['app' => $app ]);
}
if (str_starts_with($image, 'filetypes/') && file_exists(\OC::$SERVERROOT . '/core/img/' . $image)) {
if (str_starts_with($image, 'filetypes/') && file_exists(Kernel::getInstance()->getServerRoot() . '/core/img/' . $image)) {
$route = $this->urlGenerator->linkToRoute('theming.Icon.getThemedIcon', ['app' => $app, 'image' => $image]);
}
-2
View File
@@ -11,8 +11,6 @@ OC.L10N.register(
"Your password will expire today." : "Je wachtwoord vervalt vandaag.",
"_Your password will expire within %n day._::_Your password will expire within %n days._" : ["Je wachtwoord verloopt binnen %n dag.","Je wachtwoord vervalt over %n dagen."],
"LDAP/AD integration" : "LDAP/AD integratie",
"_%n group found_::_%n groups found_" : ["%n groep gevonden","%n groepen gevonden"],
"_%n user found_::_%n users found_" : ["%n gebruiker gevonden","%n gebruikers gevonden"],
"Could not detect user display name attribute. Please specify it yourself in advanced LDAP settings." : "Kon het weergavenaam attribuut van de gebruiker niet vinden. Geef het zelf op in de geavanceerde LDAP instellingen.",
"Could not find the desired feature" : "Kon de gewenste functie niet vinden",
"Invalid Host" : "Ongeldige server",
-2
View File
@@ -9,8 +9,6 @@
"Your password will expire today." : "Je wachtwoord vervalt vandaag.",
"_Your password will expire within %n day._::_Your password will expire within %n days._" : ["Je wachtwoord verloopt binnen %n dag.","Je wachtwoord vervalt over %n dagen."],
"LDAP/AD integration" : "LDAP/AD integratie",
"_%n group found_::_%n groups found_" : ["%n groep gevonden","%n groepen gevonden"],
"_%n user found_::_%n users found_" : ["%n gebruiker gevonden","%n gebruikers gevonden"],
"Could not detect user display name attribute. Please specify it yourself in advanced LDAP settings." : "Kon het weergavenaam attribuut van de gebruiker niet vinden. Geef het zelf op in de geavanceerde LDAP instellingen.",
"Could not find the desired feature" : "Kon de gewenste functie niet vinden",
"Invalid Host" : "Ongeldige server",
@@ -84,7 +84,7 @@ class WebhookListenerMapper extends QBMapper {
?array $authData,
?array $tokenNeeded = [],
): WebhookListener {
/* Remove any superfluous backslash */
/* Remove any superfluous antislash */
$event = ltrim($event, '\\');
if (!class_exists($event) || !is_a($event, IWebhookCompatibleEvent::class, true)) {
throw new \UnexpectedValueException("$event is not an event class compatible with webhooks");
@@ -126,7 +126,7 @@ class WebhookListenerMapper extends QBMapper {
?array $authData,
?array $tokenNeeded = [],
): WebhookListener {
/* Remove any superfluous backslash */
/* Remove any superfluous antislash */
$event = ltrim($event, '\\');
if (!class_exists($event) || !is_a($event, IWebhookCompatibleEvent::class, true)) {
throw new \UnexpectedValueException("$event is not an event class compatible with webhooks");
@@ -12,6 +12,8 @@ use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\ResponseInterface;
class CalDavContext implements \Behat\Behat\Context\Context {
/** @var string */
private $baseUrl;
/** @var Client */
private $client;
/** @var ResponseInterface */
@@ -22,9 +24,9 @@ class CalDavContext implements \Behat\Behat\Context\Context {
/**
* @param string $baseUrl
*/
public function __construct(
private $baseUrl,
) {
public function __construct($baseUrl) {
$this->baseUrl = $baseUrl;
// in case of ci deployment we take the server url from the environment
$testServerUrl = getenv('TEST_SERVER_URL');
if ($testServerUrl !== false) {
@@ -12,6 +12,8 @@ use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Message\ResponseInterface;
class CardDavContext implements \Behat\Behat\Context\Context {
/** @var string */
private $baseUrl;
/** @var Client */
private $client;
/** @var ResponseInterface */
@@ -19,9 +21,12 @@ class CardDavContext implements \Behat\Behat\Context\Context {
/** @var string */
private $responseXml = '';
public function __construct(
private string $baseUrl,
) {
/**
* @param string $baseUrl
*/
public function __construct($baseUrl) {
$this->baseUrl = $baseUrl;
// in case of ci deployment we take the server url from the environment
$testServerUrl = getenv('TEST_SERVER_URL');
if ($testServerUrl !== false) {
@@ -11,14 +11,19 @@ use GuzzleHttp\Client;
use GuzzleHttp\Message\ResponseInterface;
class ChecksumsContext implements \Behat\Behat\Context\Context {
/** @var string */
private $baseUrl;
/** @var Client */
private $client;
/** @var ResponseInterface */
private $response;
public function __construct(
private string $baseUrl,
) {
/**
* @param string $baseUrl
*/
public function __construct($baseUrl) {
$this->baseUrl = $baseUrl;
// in case of ci deployment we take the server url from the environment
$testServerUrl = getenv('TEST_SERVER_URL');
if ($testServerUrl !== false) {
@@ -17,12 +17,13 @@ class CommandLineContext implements \Behat\Behat\Context\Context {
private $lastTransferPath;
private $featureContext;
private $localBaseUrl;
private $remoteBaseUrl;
public function __construct(
$ocPath,
private $baseUrl,
) {
public function __construct($ocPath, $baseUrl) {
$this->ocPath = rtrim($ocPath, '/') . '/';
$this->localBaseUrl = $baseUrl;
$this->remoteBaseUrl = $baseUrl;
}
/**
@@ -8,6 +8,8 @@
require __DIR__ . '/autoload.php';
class CommentsContext implements \Behat\Behat\Context\Context {
/** @var string */
private $baseUrl;
/** @var array */
private $response;
/** @var int */
@@ -18,9 +20,9 @@ class CommentsContext implements \Behat\Behat\Context\Context {
/**
* @param string $baseUrl
*/
public function __construct(
private $baseUrl,
) {
public function __construct($baseUrl) {
$this->baseUrl = $baseUrl;
// in case of ci deployment we take the server url from the environment
$testServerUrl = getenv('TEST_SERVER_URL');
if ($testServerUrl !== false) {
@@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
@@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
@@ -16,12 +16,13 @@ use GuzzleHttp\Utils;
use Psr\Http\Message\ResponseInterface;
class PrincipalPropertySearchContext implements Context {
private string $baseUrl;
private Client $client;
private ResponseInterface $response;
public function __construct(
private string $baseUrl,
) {
public function __construct(string $baseUrl) {
$this->baseUrl = $baseUrl;
// in case of ci deployment we take the server url from the environment
$testServerUrl = getenv('TEST_SERVER_URL');
if ($testServerUrl !== false) {
@@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
@@ -5,14 +5,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
use Behat\Behat\Context\Context;
use OC\Remote\Api\OCS;
use OC\Remote\Credentials;
use OC\Remote\Instance;
use OC\Remote\User;
use OCP\Http\Client\IClientService;
use OCP\ICacheFactory;
use OCP\IConfig;
use OCP\Server;
use PHPUnit\Framework\Assert;
require __DIR__ . '/autoload.php';
@@ -21,25 +14,26 @@ require __DIR__ . '/autoload.php';
* Remote context.
*/
class RemoteContext implements Context {
/** @var Instance */
/** @var \OC\Remote\Instance */
protected $remoteInstance;
/** @var Credentials */
/** @var \OC\Remote\Credentials */
protected $credentails;
/** @var User */
/** @var \OC\Remote\User */
protected $userResult;
protected $remoteUrl;
protected $lastException;
public function __construct(
private string $remote,
) {
public function __construct($remote) {
require_once __DIR__ . '/../../../../lib/base.php';
$this->remoteUrl = $remote;
}
protected function getApiClient() {
return new OCS($this->remoteInstance, $this->credentails, Server::get(IClientService::class));
return new \OC\Remote\Api\OCS($this->remoteInstance, $this->credentails, \OC::$server->get(IClientService::class));
}
/**
@@ -49,13 +43,13 @@ class RemoteContext implements Context {
*/
public function selectRemoteInstance($remoteServer) {
if ($remoteServer == 'REMOTE') {
$baseUri = $this->remote;
$baseUri = $this->remoteUrl;
} else {
$baseUri = 'nonexistingnextcloudserver.local';
}
$this->lastException = null;
try {
$this->remoteInstance = new Instance($baseUri, Server::get(ICacheFactory::class)->createLocal(), Server::get(IClientService::class));
$this->remoteInstance = new \OC\Remote\Instance($baseUri, \OC::$server->getMemCacheFactory()->createLocal(), \OC::$server->get(IClientService::class));
// trigger the status request
$this->remoteInstance->getProtocol();
} catch (\Exception $e) {
@@ -69,7 +63,7 @@ class RemoteContext implements Context {
*/
public function theRemoteVersionShouldBe($version) {
if ($version === '__current_version__') {
$version = Server::get(IConfig::class)->getSystemValue('version', '0.0.0.0');
$version = \OC::$server->getConfig()->getSystemValue('version', '0.0.0.0');
}
Assert::assertEquals($version, $this->remoteInstance->getVersion());
@@ -89,7 +83,7 @@ class RemoteContext implements Context {
* @param string $password
*/
public function usingCredentials($user, $password) {
$this->credentails = new Credentials($user, $password);
$this->credentails = new \OC\Remote\Credentials($user, $password);
}
/**
@@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
@@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
@@ -619,9 +619,9 @@ trait Sharing {
} elseif ($contentExpected === 'A_TOKEN') {
// A token is composed by 15 characters from
// ISecureRandom::CHAR_HUMAN_READABLE.
Assert::assertMatchesRegularExpression('/^[abcdefgijkmnopqrstwxyzABCDEFGHJKLMNPQRSTWXYZ23456789]{15}$/', (string)$returnedShare->$field, "Field '$field' is not a token");
Assert::assertRegExp('/^[abcdefgijkmnopqrstwxyzABCDEFGHJKLMNPQRSTWXYZ23456789]{15}$/', (string)$returnedShare->$field, "Field '$field' is not a token");
} elseif (strpos($contentExpected, 'REGEXP ') === 0) {
Assert::assertMatchesRegularExpression(substr($contentExpected, strlen('REGEXP ')), (string)$returnedShare->$field, "Field '$field' does not match");
Assert::assertRegExp(substr($contentExpected, strlen('REGEXP ')), (string)$returnedShare->$field, "Field '$field' does not match");
} else {
Assert::assertEquals($contentExpected, (string)$returnedShare->$field, "Field '$field' does not match");
}
@@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
@@ -12,6 +12,8 @@ use GuzzleHttp\Client;
use GuzzleHttp\Message\ResponseInterface;
class TagsContext implements \Behat\Behat\Context\Context {
/** @var string */
private $baseUrl;
/** @var Client */
private $client;
/** @var ResponseInterface */
@@ -20,9 +22,9 @@ class TagsContext implements \Behat\Behat\Context\Context {
/**
* @param string $baseUrl
*/
public function __construct(
private $baseUrl,
) {
public function __construct($baseUrl) {
$this->baseUrl = $baseUrl;
// in case of ci deployment we take the server url from the environment
$testServerUrl = getenv('TEST_SERVER_URL');
if ($testServerUrl !== false) {
@@ -1,7 +1,5 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
+54
View File
@@ -444,6 +444,11 @@
<code><![CDATA[$this->principalUri]]></code>
</InvalidArgument>
</file>
<file src="apps/dav/lib/Command/CreateCalendar.php">
<DeprecatedMethod>
<code><![CDATA[getL10NFactory]]></code>
</DeprecatedMethod>
</file>
<file src="apps/dav/lib/Command/SendEventReminders.php">
<DeprecatedMethod>
<code><![CDATA[getAppValue]]></code>
@@ -770,6 +775,11 @@
<code><![CDATA[bool]]></code>
</InvalidReturnType>
</file>
<file src="apps/dav/lib/Files/RootCollection.php">
<DeprecatedMethod>
<code><![CDATA[getUserFolder]]></code>
</DeprecatedMethod>
</file>
<file src="apps/dav/lib/Listener/CalendarDeletionDefaultUpdaterListener.php">
<DeprecatedMethod>
<code><![CDATA[deleteUserValue]]></code>
@@ -820,6 +830,7 @@
<file src="apps/dav/lib/RootCollection.php">
<DeprecatedMethod>
<code><![CDATA[getL10N]]></code>
<code><![CDATA[getL10NFactory]]></code>
</DeprecatedMethod>
</file>
<file src="apps/dav/lib/Search/ContactsSearchProvider.php">
@@ -1516,6 +1527,9 @@
<DeprecatedInterface>
<code><![CDATA[Storage]]></code>
</DeprecatedInterface>
<DeprecatedMethod>
<code><![CDATA[Util::isSharingDisabledForUser()]]></code>
</DeprecatedMethod>
</file>
<file src="apps/files_sharing/lib/Helper.php">
<DeprecatedMethod>
@@ -1596,6 +1610,24 @@
<code><![CDATA[getUserValue]]></code>
</DeprecatedMethod>
</file>
<file src="apps/files_sharing/lib/ShareBackend/File.php">
<InternalClass>
<code><![CDATA[new View('/' . $shareWith . '/files')]]></code>
</InternalClass>
<InternalMethod>
<code><![CDATA[is_dir]]></code>
<code><![CDATA[is_dir]]></code>
<code><![CDATA[mkdir]]></code>
<code><![CDATA[new View('/' . $shareWith . '/files')]]></code>
</InternalMethod>
<InvalidArgument>
<code><![CDATA[$itemSource]]></code>
<code><![CDATA[$itemSource]]></code>
</InvalidArgument>
<MoreSpecificImplementedParamType>
<code><![CDATA[$shareWith]]></code>
</MoreSpecificImplementedParamType>
</file>
<file src="apps/files_sharing/lib/SharedMount.php">
<InvalidReturnType>
<code><![CDATA[bool]]></code>
@@ -1609,6 +1641,7 @@
<code><![CDATA[Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info)]]></code>
<code><![CDATA[Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info)]]></code>
<code><![CDATA[Util::emitHook('\OC\Files\Storage\Shared', 'fopen', $info)]]></code>
<code><![CDATA[Util::isSharingDisabledForUser()]]></code>
</DeprecatedMethod>
<FalsableReturnStatement>
<code><![CDATA[$this->sourceRootInfo]]></code>
@@ -2312,6 +2345,13 @@
<code><![CDATA[AlternativeHomeUserBackend]]></code>
</DeprecatedInterface>
</file>
<file src="apps/testing/lib/AppInfo/Application.php">
<DeprecatedMethod>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getConfig]]></code>
<code><![CDATA[getUserManager]]></code>
</DeprecatedMethod>
</file>
<file src="apps/testing/lib/Controller/ConfigController.php">
<DeprecatedMethod>
<code><![CDATA[deleteAppValue]]></code>
@@ -3440,6 +3480,14 @@
<code><![CDATA[self::SCAN_RECURSIVE_INCOMPLETE]]></code>
</InvalidArgument>
</file>
<file src="lib/private/Files/Cache/Storage.php">
<InvalidNullableReturnType>
<code><![CDATA[array]]></code>
</InvalidNullableReturnType>
<NullableReturnStatement>
<code><![CDATA[self::getGlobalCache()->getStorageInfo($storageId)]]></code>
</NullableReturnStatement>
</file>
<file src="lib/private/Files/Config/MountProviderCollection.php">
<InvalidOperand>
<code><![CDATA[$user]]></code>
@@ -3903,6 +3951,12 @@
<code><![CDATA[array{X-Request-Id: string, Cache-Control: string, Content-Security-Policy: string, Feature-Policy: string, X-Robots-Tag: string, Last-Modified?: string, ETag?: string, ...H}]]></code>
</MoreSpecificReturnType>
</file>
<file src="ocs-provider/index.php">
<DeprecatedMethod>
<code><![CDATA[getAppManager]]></code>
<code><![CDATA[getRequest]]></code>
</DeprecatedMethod>
</file>
<file src="public.php">
<DeprecatedMethod>
<code><![CDATA[getAppValue]]></code>
-2
View File
@@ -18,8 +18,6 @@ return (require __DIR__ . '/rector-shared.php')
$nextcloudDir . '/lib/private/Settings/AuthorizedGroupMapper.php',
$nextcloudDir . '/apps/settings/lib/Service/AuthorizedGroupService.php',
$nextcloudDir . '/lib/private/Files/Storage/Storage.php',
$nextcloudDir . '/lib/private/Files/Cache/Storage.php',
$nextcloudDir . '/lib/private/Files/Cache/StorageGlobal.php',
$nextcloudDir . '/lib/private/Files/Storage/Wrapper/Wrapper.php',
$nextcloudDir . '/build/psalm/ITypedQueryBuilderTest.php',
$nextcloudDir . '/lib/private/DB/QueryBuilder/TypedQueryBuilder.php',
-1
View File
@@ -27,7 +27,6 @@ return (require 'rector-shared.php')
$nextcloudDir . '/version.php',
$nextcloudDir . '/lib/private',
$nextcloudDir . '/tests',
$nextcloudDir . '/build/integration/features/bootstrap',
// $nextcloudDir . '/config',
// $nextcloudDir . '/themes',
])
+8 -110
View File
@@ -2,120 +2,18 @@
declare(strict_types=1);
use OCP\IConfig;
use OCP\IURLGenerator;
use OCP\Server;
/**
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/
use OC\Kernel\ConsoleKernel;
require_once __DIR__ . '/lib/versioncheck.php';
require_once __DIR__ . '/lib/private/Kernel/Kernel.php';
require_once __DIR__ . '/lib/private/Kernel/ConsoleKernel.php';
use OC\Console\Application;
use OCP\AppFramework\Http\Response;
use OCP\Diagnostics\IEventLogger;
use OCP\IRequest;
use OCP\Profiler\IProfiler;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Output\ConsoleOutput;
define('OC_CONSOLE', 1);
function exceptionHandler($exception) {
echo 'An unhandled exception has been thrown:' . PHP_EOL;
echo $exception;
exit(1);
}
try {
require_once __DIR__ . '/lib/base.php';
// set to run indefinitely if needed
if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
@set_time_limit(0);
}
if (!OC::$CLI) {
echo 'This script can be run from the command line only' . PHP_EOL;
exit(1);
}
$config = Server::get(IConfig::class);
set_exception_handler('exceptionHandler');
if (!function_exists('posix_getuid')) {
echo 'The posix extensions are required - see https://www.php.net/manual/en/book.posix.php' . PHP_EOL;
exit(1);
}
$user = posix_getuid();
$configUser = fileowner(OC::$configDir . 'config.php');
if ($user !== $configUser) {
echo 'Console has to be executed with the user that owns the file config/config.php' . PHP_EOL;
echo 'Current user id: ' . $user . PHP_EOL;
echo 'Owner id of config.php: ' . $configUser . PHP_EOL;
echo "Try adding 'sudo -u #" . $configUser . "' to the beginning of the command (without the single quotes)" . PHP_EOL;
echo "If running with 'docker exec' try adding the option '-u " . $configUser . "' to the docker command (without the single quotes)" . PHP_EOL;
exit(1);
}
$oldWorkingDir = getcwd();
if ($oldWorkingDir === false) {
echo 'This script can be run from the Nextcloud root directory only.' . PHP_EOL;
echo "Can't determine current working dir - the script will continue to work but be aware of the above fact." . PHP_EOL;
} elseif ($oldWorkingDir !== __DIR__ && !chdir(__DIR__)) {
echo 'This script can be run from the Nextcloud root directory only.' . PHP_EOL;
echo "Can't change to Nextcloud root directory." . PHP_EOL;
exit(1);
}
if (!(function_exists('pcntl_signal') && function_exists('pcntl_signal_dispatch')) && !in_array('--no-warnings', $argv)) {
echo 'The process control (PCNTL) extensions are required in case you want to interrupt long running commands - see https://www.php.net/manual/en/book.pcntl.php' . PHP_EOL;
echo "Additionally the function 'pcntl_signal' and 'pcntl_signal_dispatch' need to be enabled in your php.ini." . PHP_EOL;
}
$eventLogger = Server::get(IEventLogger::class);
$eventLogger->start('console:build_application', 'Build Application instance and load commands');
$application = Server::get(Application::class);
/* base.php will have removed eventual debug options from argv in $_SERVER */
$argv = $_SERVER['argv'];
$input = new ArgvInput($argv);
$output = new ConsoleOutput();
$application->loadCommands($input, $output);
$eventLogger->end('console:build_application');
$eventLogger->start('console:run', 'Run the command');
$application->setAutoExit(false);
$exitCode = $application->run($input);
$eventLogger->end('console:run');
$profiler = Server::get(IProfiler::class);
if ($profiler->isEnabled()) {
$eventLogger->end('runtime');
$profile = $profiler->collect(Server::get(IRequest::class), new Response());
$profile->setMethod('occ');
$profile->setUrl(implode(' ', $argv));
$profiler->saveProfile($profile);
$urlGenerator = Server::get(IURLGenerator::class);
$url = $urlGenerator->linkToRouteAbsolute('profiler.main.profiler', [
'profiler' => 'db',
'token' => $profile->getToken(),
]);
$output->getErrorOutput()->writeln('Profiler output available at ' . $url);
}
if ($exitCode > 255) {
$exitCode = 255;
}
exit($exitCode);
} catch (Exception $ex) {
exceptionHandler($ex);
} catch (Error $ex) {
exceptionHandler($ex);
}
(new ConsoleKernel())
->boot()
->run($_SERVER['argv']);
+15 -13
View File
@@ -9,6 +9,10 @@ namespace OC\Core\Controller;
use OC\IntegrityCheck\Checker;
use OC\Setup;
use OCP\AppFramework\Http\RedirectResponse;
use OCP\AppFramework\Http\Response;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Services\IInitialState;
use OCP\IInitialStateService;
use OCP\IURLGenerator;
use OCP\Server;
@@ -31,7 +35,7 @@ class SetupController {
$this->autoConfigFile = \OC::$configDir . 'autoconfig.php';
}
public function run(array $post): void {
public function run(array $post): Response {
// Check for autosetup:
$post = $this->loadAutoConfig($post);
$opts = $this->setupHelper->getSystemInfo();
@@ -45,8 +49,7 @@ class SetupController {
}
if (!$this->setupHelper->canInstallFileExists()) {
$this->displaySetupForbidden();
return;
return $this->displaySetupForbidden();
}
if (isset($post['install']) && $post['install'] == 'true') {
@@ -56,21 +59,21 @@ class SetupController {
if (count($e) > 0) {
$options = array_merge($opts, $post, $errors);
$this->display($options);
return $this->display($options);
} else {
$this->finishSetup();
return $this->finishSetup();
}
} else {
$options = array_merge($opts, $post);
$this->display($options);
return $this->display($options);
}
}
private function displaySetupForbidden(): void {
$this->templateManager->printGuestPage('', 'installation_forbidden');
private function displaySetupForbidden(): TemplateResponse {
return new TemplateResponse('', 'installation_forbidden', [], TemplateResponse::RENDER_AS_GUEST);
}
public function display(array $post): void {
public function display(array $post): TemplateResponse {
$defaults = [
'adminlogin' => '',
'adminpass' => '',
@@ -103,10 +106,10 @@ class SetupController {
'adminDBConfiguration' => $this->urlGenerator->linkToDocs('admin-db-configuration'),
]);
$this->templateManager->printGuestPage('', 'installation');
return new TemplateResponse('', 'installation', [], TemplateResponse::RENDER_AS_GUEST);
}
private function finishSetup(): void {
private function finishSetup(): RedirectResponse {
if (file_exists($this->autoConfigFile)) {
unlink($this->autoConfigFile);
}
@@ -116,8 +119,7 @@ class SetupController {
$this->templateManager->printGuestPage('', 'installation_incomplete');
}
header('Location: ' . Server::get(IURLGenerator::class)->getAbsoluteURL('index.php/core/apps/recommended'));
exit();
return new RedirectResponse(Server::get(IURLGenerator::class)->getAbsoluteURL('index.php/core/apps/recommended'));
}
/**
-1
View File
@@ -204,7 +204,6 @@ OC.L10N.register(
"Search people" : "Etsi ihmisiä",
"People" : "Ihmiset",
"Filter in current view" : "Suodata nykyisessä näkymässä",
"Search connected services" : "Etsi liitetyistä palveluista",
"Results" : "Tulokset",
"Load more results" : "Lataa lisää tuloksia",
"Search in" : "Etsi kohteesta",
-1
View File
@@ -202,7 +202,6 @@
"Search people" : "Etsi ihmisiä",
"People" : "Ihmiset",
"Filter in current view" : "Suodata nykyisessä näkymässä",
"Search connected services" : "Etsi liitetyistä palveluista",
"Results" : "Tulokset",
"Load more results" : "Lataa lisää tuloksia",
"Search in" : "Etsi kohteesta",
+1 -7
View File
@@ -45,8 +45,6 @@ OC.L10N.register(
"Input text is too long" : "De ingevoerde tekst is te lang",
"Requested task type does not exist" : "Het aangevraagde taaktype bestaat niet",
"Necessary language model provider is not available" : "De nodige taalmodel provider is niet beschikbaar",
"Cannot generate more than 12 images" : "Kan niet meer dan 12 afbeeldingen genereren",
"Cannot generate less than 1 image" : "Kan niet minder dan 1 afbeelding genereren",
"No text to image provider is available" : "Geen text naar afbeelding aanbieder beschikbaar",
"Image not found" : "Afbeelding niet gevonden",
"No translation provider available" : "Geen provider voor vertaling beschikbaar",
@@ -281,7 +279,7 @@ OC.L10N.register(
"Your files are encrypted. There will be no way to get your data back after your password is reset. If you are not sure what to do, please contact your administrator before you continue. Do you really want to continue?" : "Je bestanden zijn versleuteld. Het is niet mogelijk om je gegevens terug te krijgen als je wachtwoord wordt gereset. Als je niet zeker weer wat je moet doen, neem dan contact op met je beheerder voordat je verdergaat. Wil je echt verder gaan?",
"I know what I'm doing" : "Ik weet wat ik doe",
"Resetting password" : "Resetten wachtwoord",
"Schedule work & meetings, synced with all your devices." : "Plan je werk & vergaderingen, gesynchroniseerd met al je apparaten.",
"Schedule work & meetings, synced with all your devices." : "Plan je werk & afspraken, gesynced met al je toestellen.",
"Keep your colleagues and friends in one place without leaking their private info." : "Bewaar je collega's en vrienden op één plaats zonder hun persoonlijke gegevens te laten uitlekken.",
"Simple email app nicely integrated with Files, Contacts and Calendar." : "Simpele e-mailapp, handig geïntegreerd met Bestanden, Contactpersonen en Agenda.",
"Chatting, video calls, screen sharing, online meetings and web conferencing in your browser and with mobile apps." : "Chatten, videobellen, schermdelen, online vergaderingen en webconferenties - in de browser en met mobiele apps.",
@@ -308,14 +306,10 @@ OC.L10N.register(
"Loading your contacts …" : "Je contacten worden geladen ...",
"Looking for {term} …" : "Zoeken naar {term}",
"Search contacts" : "Zoek contacten",
"Filter by team" : "Filter op team",
"All teams" : "Alle teams",
"Search contacts in team {team}" : "Zoek contacten in team {team}",
"Search contacts …" : "Zoek contacten ...",
"Reset search" : "Zoekopdracht wissen",
"Could not load your contacts" : "Kon je contactpersonenen niet laden",
"No contacts found" : "Geen contacten gevonden",
"Contacts list" : "Contacten lijst",
"Show all contacts" : "Toon alle contactpersonen",
"Install the Contacts app" : "Installeer de Contacts app",
"Search" : "Zoeken",

Some files were not shown because too many files have changed in this diff Show More