Skip to content

Commit b90649d

Browse files
committed
feat: add command to get user objectstore config mappings
Signed-off-by: Robin Appelman <[email protected]>
1 parent 618a70a commit b90649d

File tree

5 files changed

+116
-8
lines changed

5 files changed

+116
-8
lines changed

apps/files/appinfo/info.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<name>Files</name>
66
<summary>File Management</summary>
77
<description>File Management</description>
8-
<version>2.1.1</version>
8+
<version>2.1.2</version>
99
<licence>agpl</licence>
1010
<author>John Molakvoæ</author>
1111
<author>Robin Appelman</author>
@@ -44,6 +44,7 @@
4444
<command>OCA\Files\Command\Object\Delete</command>
4545
<command>OCA\Files\Command\Object\Get</command>
4646
<command>OCA\Files\Command\Object\Put</command>
47+
<command>OCA\Files\Command\Object\Multi\Users</command>
4748
</commands>
4849

4950
<activity>

apps/files/composer/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
'OCA\\Files\\Command\\Move' => $baseDir . '/../lib/Command/Move.php',
3535
'OCA\\Files\\Command\\Object\\Delete' => $baseDir . '/../lib/Command/Object/Delete.php',
3636
'OCA\\Files\\Command\\Object\\Get' => $baseDir . '/../lib/Command/Object/Get.php',
37+
'OCA\\Files\\Command\\Object\\Multi\\Users' => $baseDir . '/../lib/Command/Object/Multi/Users.php',
3738
'OCA\\Files\\Command\\Object\\ObjectUtil' => $baseDir . '/../lib/Command/Object/ObjectUtil.php',
3839
'OCA\\Files\\Command\\Object\\Put' => $baseDir . '/../lib/Command/Object/Put.php',
3940
'OCA\\Files\\Command\\Put' => $baseDir . '/../lib/Command/Put.php',

apps/files/composer/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class ComposerStaticInitFiles
4949
'OCA\\Files\\Command\\Move' => __DIR__ . '/..' . '/../lib/Command/Move.php',
5050
'OCA\\Files\\Command\\Object\\Delete' => __DIR__ . '/..' . '/../lib/Command/Object/Delete.php',
5151
'OCA\\Files\\Command\\Object\\Get' => __DIR__ . '/..' . '/../lib/Command/Object/Get.php',
52+
'OCA\\Files\\Command\\Object\\Multi\\Users' => __DIR__ . '/..' . '/../lib/Command/Object/Multi/Users.php',
5253
'OCA\\Files\\Command\\Object\\ObjectUtil' => __DIR__ . '/..' . '/../lib/Command/Object/ObjectUtil.php',
5354
'OCA\\Files\\Command\\Object\\Put' => __DIR__ . '/..' . '/../lib/Command/Object/Put.php',
5455
'OCA\\Files\\Command\\Put' => __DIR__ . '/..' . '/../lib/Command/Put.php',
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* SPDX-FileCopyrightText: 2025 Robin Appelman <[email protected]>
6+
* SPDX-License-Identifier: AGPL-3.0-or-later
7+
*/
8+
9+
namespace OCA\Files\Command\Object\Multi;
10+
11+
use OC\Core\Command\Base;
12+
use OC\Files\ObjectStore\PrimaryObjectStoreConfig;
13+
use OCP\IConfig;
14+
use OCP\IUser;
15+
use OCP\IUserManager;
16+
use Symfony\Component\Console\Input\InputInterface;
17+
use Symfony\Component\Console\Input\InputOption;
18+
use Symfony\Component\Console\Output\OutputInterface;
19+
20+
class Users extends Base {
21+
public function __construct(
22+
private IUserManager $userManager,
23+
private PrimaryObjectStoreConfig $objectStoreConfig,
24+
private IConfig $config,
25+
) {
26+
parent::__construct();
27+
}
28+
29+
protected function configure(): void {
30+
parent::configure();
31+
$this
32+
->setName('files:object:multi:users')
33+
->setDescription('Get the mapping between users and object store buckets')
34+
->addOption('bucket', 'b', InputOption::VALUE_REQUIRED, 'Only list users using the specified bucket')
35+
->addOption('object-store', 'o', InputOption::VALUE_REQUIRED, 'Only list users using the specified object store configuration')
36+
->addOption('user', 'u', InputOption::VALUE_REQUIRED, 'Only show the mapping for the specified user, ignores all other options');
37+
}
38+
39+
public function execute(InputInterface $input, OutputInterface $output): int {
40+
if ($userId = $input->getOption('user')) {
41+
$user = $this->userManager->get($userId);
42+
if (!$user) {
43+
$output->writeln("<error>User $userId not found</error>");
44+
return 1;
45+
}
46+
$users = new \ArrayIterator([$user]);
47+
} else {
48+
$bucket = (string) $input->getOption('bucket');
49+
$objectStore = (string) $input->getOption('object-store');
50+
if ($bucket !== '' && $objectStore === '') {
51+
$users = $this->getUsers($this->config->getUsersForUserValue('homeobjectstore', 'bucket', $bucket));
52+
} elseif ($bucket === '' && $objectStore !== '') {
53+
$users = $this->getUsers($this->config->getUsersForUserValue('homeobjectstore', 'objectstore', $objectStore));
54+
} elseif ($bucket) {
55+
$users = $this->getUsers(array_intersect(
56+
$this->config->getUsersForUserValue('homeobjectstore', 'bucket', $bucket),
57+
$this->config->getUsersForUserValue('homeobjectstore', 'objectstore', $objectStore)
58+
));
59+
} else {
60+
$users = $this->userManager->getSeenUsers();
61+
}
62+
}
63+
64+
$this->writeStreamingTableInOutputFormat($input, $output, $this->infoForUsers($users), 100);
65+
return 0;
66+
}
67+
68+
/**
69+
* @param string[] $userIds
70+
* @return \Iterator<IUser>
71+
*/
72+
private function getUsers(array $userIds): \Iterator {
73+
foreach ($userIds as $userId) {
74+
$user = $this->userManager->get($userId);
75+
if ($user) {
76+
yield $user;
77+
}
78+
}
79+
}
80+
81+
/**
82+
* @param \Iterator<IUser> $users
83+
* @return \Iterator<array>
84+
*/
85+
private function infoForUsers(\Iterator $users): \Iterator {
86+
foreach ($users as $user) {
87+
yield $this->infoForUser($user);
88+
}
89+
}
90+
91+
private function infoForUser(IUser $user): array {
92+
return [
93+
'user' => $user->getUID(),
94+
'object-store' => $this->objectStoreConfig->getObjectStoreForUser($user),
95+
'bucket' => $this->objectStoreConfig->getSetBucketForUser($user) ?? 'unset',
96+
];
97+
}
98+
}

lib/private/Files/ObjectStore/PrimaryObjectStoreConfig.php

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,12 @@ public function getObjectStoreConfigForUser(IUser $user): ?array {
6161
return null;
6262
}
6363

64-
$store = $this->config->getUserValue($user->getUID(), 'homeobjectstore', 'objectstore', null);
64+
$store = $this->getObjectStoreForUser($user);
6565

66-
if ($store) {
67-
$config = $configs[$store];
68-
} else {
69-
$config = $configs['default'];
66+
if (!isset($configs[$store])) {
67+
throw new \Exception("Object store configuration for '{$store}' not found");
7068
}
69+
$config = $configs[$store];
7170

7271
if ($config['arguments']['multibucket']) {
7372
$config['arguments']['bucket'] = $this->getBucketForUser($user, $config);
@@ -141,8 +140,8 @@ private function validateObjectStoreConfig(array $config) {
141140
];
142141
}
143142

144-
private function getBucketForUser(IUser $user, array $config): string {
145-
$bucket = $this->config->getUserValue($user->getUID(), 'homeobjectstore', 'bucket', null);
143+
public function getBucketForUser(IUser $user, array $config): string {
144+
$bucket = $this->getSetBucketForUser($user);
146145

147146
if ($bucket === null) {
148147
/*
@@ -161,4 +160,12 @@ private function getBucketForUser(IUser $user, array $config): string {
161160

162161
return $bucket;
163162
}
163+
164+
public function getSetBucketForUser(IUser $user): ?string {
165+
return $this->config->getUserValue($user->getUID(), 'homeobjectstore', 'bucket', null);
166+
}
167+
168+
public function getObjectStoreForUser(IUser $user): string {
169+
return $this->config->getUserValue($user->getUID(), 'homeobjectstore', 'objectstore', 'default');
170+
}
164171
}

0 commit comments

Comments
 (0)