Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

use OCA\Files\Event\LoadAdditionalScriptsEvent;
use OCA\Guests\Capabilities;
use OCA\Guests\ConfigLexicon;
use OCA\Guests\GroupBackend;
use OCA\Guests\Hooks;
use OCA\Guests\Listener\BeforeUserManagementRenderedListener;
Expand Down Expand Up @@ -47,6 +48,7 @@
$context->registerEventListener(ShareCreatedEvent::class, ShareAutoAcceptListener::class);
$context->registerEventListener(BeforeTemplateRenderedEvent::class, TalkIntegrationListener::class);
$context->registerEventListener(BeforeUserManagementRenderedEvent::class, BeforeUserManagementRenderedListener::class);
$context->registerConfigLexicon(ConfigLexicon::class);

Check failure on line 51 in lib/AppInfo/Application.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable30

MissingDependency

lib/AppInfo/Application.php:51:35: MissingDependency: OCA\Guests\ConfigLexicon depends on class or interface ocp\config\lexicon\ilexicon that does not exist (see https://psalm.dev/157)

Check failure on line 51 in lib/AppInfo/Application.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable30

UndefinedInterfaceMethod

lib/AppInfo/Application.php:51:13: UndefinedInterfaceMethod: Method OCP\AppFramework\Bootstrap\IRegistrationContext::registerConfigLexicon does not exist (see https://psalm.dev/181)

Check failure on line 51 in lib/AppInfo/Application.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

MissingDependency

lib/AppInfo/Application.php:51:35: MissingDependency: OCA\Guests\ConfigLexicon depends on class or interface ocp\config\lexicon\ilexicon that does not exist (see https://psalm.dev/157)
}

public function boot(IBootContext $context): void {
Expand Down
48 changes: 17 additions & 31 deletions lib/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@

use OCP\AppFramework\Services\IAppConfig;
use OCP\Group\ISubAdmin;
use OCP\IAppConfig as IGlobalAppConfig;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\IUserSession;

class Config {
public function __construct(
private IConfig $config,
private IGlobalAppConfig $globalAppConfig,
private IAppConfig $appConfig,
private ISubAdmin $subAdmin,
private IUserSession $userSession,
Expand All @@ -25,62 +27,46 @@
}

public function allowExternalStorage(): bool {
return $this->appConfig->getAppValueBool('allow_external_storage', false);
return $this->appConfig->getAppValueBool(ConfigLexicon::EXTERNAL_STORAGE_ENABLED);

Check failure on line 30 in lib/Config.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable30

MissingDependency

lib/Config.php:30:44: MissingDependency: OCA\Guests\ConfigLexicon depends on class or interface ocp\config\lexicon\ilexicon that does not exist (see https://psalm.dev/157)

Check failure on line 30 in lib/Config.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

MissingDependency

lib/Config.php:30:44: MissingDependency: OCA\Guests\ConfigLexicon depends on class or interface ocp\config\lexicon\ilexicon that does not exist (see https://psalm.dev/157)
}

/**
* @param string|bool $allow
*/
public function setAllowExternalStorage($allow) {
$this->appConfig->setAppValueBool('allow_external_storage', $allow === true || $allow === 'true') ;
public function setAllowExternalStorage(bool $allow): void {
$this->appConfig->setAppValueBool(ConfigLexicon::EXTERNAL_STORAGE_ENABLED, $allow);

Check failure on line 34 in lib/Config.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable30

MissingDependency

lib/Config.php:34:37: MissingDependency: OCA\Guests\ConfigLexicon depends on class or interface ocp\config\lexicon\ilexicon that does not exist (see https://psalm.dev/157)

Check failure on line 34 in lib/Config.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

MissingDependency

lib/Config.php:34:37: MissingDependency: OCA\Guests\ConfigLexicon depends on class or interface ocp\config\lexicon\ilexicon that does not exist (see https://psalm.dev/157)
}

public function hideOtherUsers(): bool {
return $this->appConfig->getAppValueBool('hide_users', true);
return $this->appConfig->getAppValueBool(ConfigLexicon::HIDE_OTHER_ACCOUNTS);

Check failure on line 38 in lib/Config.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable30

MissingDependency

lib/Config.php:38:44: MissingDependency: OCA\Guests\ConfigLexicon depends on class or interface ocp\config\lexicon\ilexicon that does not exist (see https://psalm.dev/157)

Check failure on line 38 in lib/Config.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

MissingDependency

lib/Config.php:38:44: MissingDependency: OCA\Guests\ConfigLexicon depends on class or interface ocp\config\lexicon\ilexicon that does not exist (see https://psalm.dev/157)
}

/**
* @param string|bool $hide
*/
public function setHideOtherUsers($hide): void {
$this->appConfig->setAppValueBool('hide_users', $hide === true || $hide === 'true') ;
public function setHideOtherUsers(bool $hide): void {
$this->appConfig->setAppValueBool(ConfigLexicon::HIDE_OTHER_ACCOUNTS, $hide);

Check failure on line 42 in lib/Config.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable30

MissingDependency

lib/Config.php:42:37: MissingDependency: OCA\Guests\ConfigLexicon depends on class or interface ocp\config\lexicon\ilexicon that does not exist (see https://psalm.dev/157)

Check failure on line 42 in lib/Config.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

MissingDependency

lib/Config.php:42:37: MissingDependency: OCA\Guests\ConfigLexicon depends on class or interface ocp\config\lexicon\ilexicon that does not exist (see https://psalm.dev/157)
}

public function getHome(string $uid): string {
return $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/' . $uid;
}

public function useWhitelist(): bool {
return $this->appConfig->getAppValueBool('usewhitelist', true);
return $this->appConfig->getAppValueBool(ConfigLexicon::WHITE_LIST_ENABLED);

Check failure on line 50 in lib/Config.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable30

MissingDependency

lib/Config.php:50:44: MissingDependency: OCA\Guests\ConfigLexicon depends on class or interface ocp\config\lexicon\ilexicon that does not exist (see https://psalm.dev/157)

Check failure on line 50 in lib/Config.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

MissingDependency

lib/Config.php:50:44: MissingDependency: OCA\Guests\ConfigLexicon depends on class or interface ocp\config\lexicon\ilexicon that does not exist (see https://psalm.dev/157)
}

/**
* @param string|bool $use
*/
public function setUseWhitelist($use) {
$this->appConfig->setAppValueBool('usewhitelist', $use === true || $use === 'true') ;
public function setUseWhitelist(bool $use): void {
$this->appConfig->setAppValueBool(ConfigLexicon::WHITE_LIST_ENABLED, $use);

Check failure on line 54 in lib/Config.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable30

MissingDependency

lib/Config.php:54:37: MissingDependency: OCA\Guests\ConfigLexicon depends on class or interface ocp\config\lexicon\ilexicon that does not exist (see https://psalm.dev/157)

Check failure on line 54 in lib/Config.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

MissingDependency

lib/Config.php:54:37: MissingDependency: OCA\Guests\ConfigLexicon depends on class or interface ocp\config\lexicon\ilexicon that does not exist (see https://psalm.dev/157)
}

/**
* @return string[]
*/
public function getAppWhitelist(): array {
$whitelist = $this->appConfig->getAppValueString('whitelist', AppWhitelist::DEFAULT_WHITELIST);
return explode(',', $whitelist);
return explode(',', $this->appConfig->getAppValueString(ConfigLexicon::WHITE_LIST));

Check failure on line 61 in lib/Config.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable30

MissingDependency

lib/Config.php:61:59: MissingDependency: OCA\Guests\ConfigLexicon depends on class or interface ocp\config\lexicon\ilexicon that does not exist (see https://psalm.dev/157)

Check failure on line 61 in lib/Config.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

MissingDependency

lib/Config.php:61:59: MissingDependency: OCA\Guests\ConfigLexicon depends on class or interface ocp\config\lexicon\ilexicon that does not exist (see https://psalm.dev/157)
}

/**
* @param array|string $whitelist
*/
public function setAppWhitelist($whitelist): void {
if (is_array($whitelist)) {
$whitelist = implode(',', $whitelist);
}
$this->appConfig->setAppValueString('whitelist', $whitelist);
public function setAppWhitelist(array $whitelist): void {
$this->appConfig->setAppValueString(ConfigLexicon::WHITE_LIST, implode(',', $whitelist));

Check failure on line 65 in lib/Config.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable30

MissingDependency

lib/Config.php:65:39: MissingDependency: OCA\Guests\ConfigLexicon depends on class or interface ocp\config\lexicon\ilexicon that does not exist (see https://psalm.dev/157)

Check failure on line 65 in lib/Config.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

MissingDependency

lib/Config.php:65:39: MissingDependency: OCA\Guests\ConfigLexicon depends on class or interface ocp\config\lexicon\ilexicon that does not exist (see https://psalm.dev/157)
}

public function isSharingRestrictedToGroup(): bool {
return $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
return $this->globalAppConfig->getValueBool('core', 'shareapi_only_share_with_group_members');
}

public function canCreateGuests(): bool {
Expand Down Expand Up @@ -114,7 +100,7 @@
* @return string[]
*/
public function getCreateRestrictedToGroup(): array {
$groups = $this->appConfig->getAppValueArray('create_restricted_to_group', []);
$groups = $this->appConfig->getAppValueArray(ConfigLexicon::GROUP_LIMITATION);

Check failure on line 103 in lib/Config.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

MissingDependency

lib/Config.php:103:48: MissingDependency: OCA\Guests\ConfigLexicon depends on class or interface ocp\config\lexicon\ilexicon that does not exist (see https://psalm.dev/157)
// If empty, it means there is no restriction
if (empty($groups)) {
return [];
Expand All @@ -123,7 +109,7 @@
// It does not matter at this point if the admin
// group is in the list or not. We are checking it
// anyway in the canCreateGuests method.
return array_values(array_unique($this->appConfig->getAppValueArray('create_restricted_to_group', [])));
return array_values(array_unique($this->appConfig->getAppValueArray(ConfigLexicon::GROUP_LIMITATION)));
}

/**
Expand Down
57 changes: 57 additions & 0 deletions lib/ConfigLexicon.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Guests;

use OCP\Config\Lexicon\Entry;
use OCP\Config\Lexicon\ILexicon;
use OCP\Config\Lexicon\Preset;
use OCP\Config\Lexicon\Strictness;
use OCP\Config\ValueType;

/**
* Config Lexicon for guests app.
*
* Please Add & Manage your Config Keys in that file and keep the Lexicon up to date!
*
* {@see ILexicon}
*/
class ConfigLexicon implements ILexicon {
public const HIDE_OTHER_ACCOUNTS = 'hide_users';
public const EXTERNAL_STORAGE_ENABLED = 'allow_external_storage';
public const WHITE_LIST_ENABLED = 'usewhitelist';
public const WHITE_LIST = 'whitelist';
public const GROUP_LIMITATION = 'create_restricted_to_group';
public const GUEST_DISK_QUOTA = 'guest_quota';
public const USER_CREATED_BY = 'created_by';

public function getStrictness(): Strictness {
return Strictness::NOTICE;
}

public function getAppConfigs(): array {
return [
new Entry(self::EXTERNAL_STORAGE_ENABLED, ValueType::BOOL, false, 'permit guests to access to external storage'),
new Entry(self::HIDE_OTHER_ACCOUNTS, ValueType::BOOL, true, 'hide other accounts to guests'),
new Entry(self::WHITE_LIST_ENABLED, ValueType::BOOL, true, 'enable a white listing of limited apps made available to guests'),
new Entry(self::WHITE_LIST, ValueType::STRING, AppWhitelist::DEFAULT_WHITELIST, 'list of white listed apps available to guests'),
new Entry(self::GUEST_DISK_QUOTA, ValueType::STRING, defaultRaw: fn (Preset $p): string => match ($p) {
Preset::PRIVATE, Preset::FAMILY => '1 GB',
Preset::SMALL, Preset::MEDIUM, Preset::LARGE => '10 GB',
default => '0 B',
}, definition: 'set default disk quota assigned to guest account at its creation'),
new Entry(self::GROUP_LIMITATION, ValueType::ARRAY, []),
];
}

public function getUserConfigs(): array {
return [
new Entry(self::USER_CREATED_BY, ValueType::STRING, null, 'user that generated this guest account'),
];
}
}
12 changes: 7 additions & 5 deletions lib/Controller/SettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
use OCA\Guests\AppInfo\Application;
use OCA\Guests\AppWhitelist;
use OCA\Guests\Config;
use OCA\Guests\ConfigLexicon;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Services\IAppConfig;
use OCP\IRequest;

/**
Expand All @@ -22,11 +24,11 @@
* @package OCA\Guests\Controller
*/
class SettingsController extends Controller {

public function __construct(
IRequest $request,
private Config $config,
private AppWhitelist $appWhitelist,
private readonly Config $config,
private readonly IAppConfig $appConfig,
private readonly AppWhitelist $appWhitelist,
) {
parent::__construct(Application::APP_ID, $request);
}
Expand Down Expand Up @@ -94,9 +96,9 @@ public function getWhitelist(): DataResponse {
* @return DataResponse with the reset whitelist
*/
public function resetWhitelist(): DataResponse {
$this->config->setAppWhitelist(AppWhitelist::DEFAULT_WHITELIST);
$this->appConfig->deleteAppValue(ConfigLexicon::WHITE_LIST);
return new DataResponse([
'whitelist' => explode(',', AppWhitelist::DEFAULT_WHITELIST),
'whitelist' => $this->config->getAppWhitelist(),
]);
}
}
15 changes: 11 additions & 4 deletions lib/GuestManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

namespace OCA\Guests;

use OCA\Guests\AppInfo\Application;
use OCP\AppFramework\Services\IAppConfig;
use OCP\Config\IUserConfig;
use OCP\Config\ValueType;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IConfig;
Expand All @@ -23,6 +27,8 @@
class GuestManager {
public function __construct(
private IConfig $config,
private readonly IAppConfig $appConfig,
private readonly IUserConfig $userConfig,
private UserBackend $userBackend,
private ISecureRandom $secureRandom,
private ICrypto $crypto,
Expand Down Expand Up @@ -69,7 +75,7 @@ public function createGuest(?IUser $createdBy, string $userId, string $email, st

$user->setSystemEMailAddress($email);
if ($createdBy) {
$this->config->setUserValue($userId, 'guests', 'created_by', $createdBy->getUID());
$this->userConfig->setValueString($userId, Application::APP_ID, ConfigLexicon::USER_CREATED_BY, $createdBy->getUID());
}

if ($displayName) {
Expand Down Expand Up @@ -101,7 +107,7 @@ public function createGuest(?IUser $createdBy, string $userId, string $email, st
);
}

$user->setQuota('0 B');
$user->setQuota($this->appConfig->getAppValueString(ConfigLexicon::GUEST_DISK_QUOTA));

return $user;
}
Expand All @@ -114,7 +120,8 @@ public function getGuestsInfo(): array {
$displayNames = $this->userBackend->getDisplayNames();
$guests = array_keys($displayNames);
$shareCounts = $this->getShareCountForUsers($guests);
$createdBy = $this->config->getUserValueForUsers('guests', 'created_by', $guests);
$createdBy = $this->userConfig->getValuesByUsers(Application::APP_ID, ConfigLexicon::USER_CREATED_BY, ValueType::STRING, $guests);

return array_map(function ($uid) use ($createdBy, $displayNames, $shareCounts) {
$allSharesCount = count(array_merge(
$this->shareManager->getSharedWith($uid, IShare::TYPE_USER, null, -1, 0),
Expand All @@ -127,7 +134,7 @@ public function getGuestsInfo(): array {
'email' => $uid,
'display_name' => $displayNames[$uid] ?? $uid,
'created_by' => $createdBy[$uid] ?? '',
'share_count' => isset($shareCounts[$uid]) ? $shareCounts[$uid] : 0,
'share_count' => $shareCounts[$uid] ?? 0,
'share_count_with_circles' => $allSharesCount,
];
}, $guests);
Expand Down
Loading
Loading