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
1 change: 1 addition & 0 deletions apps/user_ldap/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
'OCA\\User_LDAP\\Settings\\Section' => $baseDir . '/../lib/Settings/Section.php',
'OCA\\User_LDAP\\SetupChecks\\LdapConnection' => $baseDir . '/../lib/SetupChecks/LdapConnection.php',
'OCA\\User_LDAP\\SetupChecks\\LdapInvalidUuids' => $baseDir . '/../lib/SetupChecks/LdapInvalidUuids.php',
'OCA\\User_LDAP\\Support\\SystemReportSection' => $baseDir . '/../lib/Support/SystemReportSection.php',
'OCA\\User_LDAP\\UserPluginManager' => $baseDir . '/../lib/UserPluginManager.php',
'OCA\\User_LDAP\\User\\DeletedUsersIndex' => $baseDir . '/../lib/User/DeletedUsersIndex.php',
'OCA\\User_LDAP\\User\\Manager' => $baseDir . '/../lib/User/Manager.php',
Expand Down
1 change: 1 addition & 0 deletions apps/user_ldap/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ class ComposerStaticInitUser_LDAP
'OCA\\User_LDAP\\Settings\\Section' => __DIR__ . '/..' . '/../lib/Settings/Section.php',
'OCA\\User_LDAP\\SetupChecks\\LdapConnection' => __DIR__ . '/..' . '/../lib/SetupChecks/LdapConnection.php',
'OCA\\User_LDAP\\SetupChecks\\LdapInvalidUuids' => __DIR__ . '/..' . '/../lib/SetupChecks/LdapInvalidUuids.php',
'OCA\\User_LDAP\\Support\\SystemReportSection' => __DIR__ . '/..' . '/../lib/Support/SystemReportSection.php',
'OCA\\User_LDAP\\UserPluginManager' => __DIR__ . '/..' . '/../lib/UserPluginManager.php',
'OCA\\User_LDAP\\User\\DeletedUsersIndex' => __DIR__ . '/..' . '/../lib/User/DeletedUsersIndex.php',
'OCA\\User_LDAP\\User\\Manager' => __DIR__ . '/..' . '/../lib/User/Manager.php',
Expand Down
2 changes: 2 additions & 0 deletions apps/user_ldap/lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use OCA\User_LDAP\Notification\Notifier;
use OCA\User_LDAP\SetupChecks\LdapConnection;
use OCA\User_LDAP\SetupChecks\LdapInvalidUuids;
use OCA\User_LDAP\Support\SystemReportSection;
use OCA\User_LDAP\User\Manager;
use OCA\User_LDAP\User_Proxy;
use OCA\User_LDAP\UserPluginManager;
Expand Down Expand Up @@ -79,6 +80,7 @@ function (ContainerInterface $c) {
$context->registerEventListener(PostLoginEvent::class, LoginListener::class);
$context->registerSetupCheck(LdapInvalidUuids::class);
$context->registerSetupCheck(LdapConnection::class);
$context->registerSystemReportSection(SystemReportSection::class);
}

#[\Override]
Expand Down
86 changes: 86 additions & 0 deletions apps/user_ldap/lib/Support/SystemReportSection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\User_LDAP\Support;

use OCA\User_LDAP\Configuration;
use OCA\User_LDAP\Helper;
use OCP\IL10N;
use OCP\SystemReport\ISystemReportSection;
use OCP\SystemReport\SystemReportDetail;
use OCP\SystemReport\SystemReportDetailFormat;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Output\BufferedOutput;

/**
* Contributes the configured LDAP backends to the system report generated
* by the support app.
*/
class SystemReportSection implements ISystemReportSection {
public function __construct(
private readonly Helper $helper,
private readonly IL10N $l10n,
) {
}

#[\Override]
public function getId(): string {
return 'ldap';
}

#[\Override]
public function getTitle(): string {
return $this->l10n->t('LDAP');
}

#[\Override]
public function getDetails(): array {
$configIds = $this->helper->getServerConfigurationPrefixes();
if ($configIds === []) {
return [];
}

$output = new BufferedOutput();
foreach ($configIds as $id) {
$configHolder = new Configuration($id);
$output->write($this->renderConfiguration($id, $configHolder->getConfiguration()));
}

return [
new SystemReportDetail(
$this->l10n->t('LDAP configuration'),
$output->fetch(),
SystemReportDetailFormat::Preformatted,
),
];
}

/** @param array<string, mixed> $configuration */
public function renderConfiguration(string $id, array $configuration): string {
ksort($configuration);

$rows = [];
foreach ($configuration as $key => $value) {
if ($key === 'ldapAgentPassword') {
$value = '***';
} elseif (is_array($value)) {
$value = implode(';', $value);
}
$rows[] = [$key, $value];
}

$output = new BufferedOutput();
$table = new Table($output);
$table->setHeaders(['Configuration', $id]);
$table->setRows($rows);
$table->render();

return $output->fetch();
}
}
3 changes: 3 additions & 0 deletions build/rector-strict.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@
$nextcloudDir . '/lib/public/AppFramework/ORM',
$nextcloudDir . '/lib/private/AppFramework/ORM',
$nextcloudDir . '/apps/oauth2',
$nextcloudDir . '/lib/public/SystemReport',
$nextcloudDir . '/lib/private/SystemReport',
$nextcloudDir . '/tests/lib/SystemReport',
])
->withAutoloadPaths([
// ensure rector properly autoload the public interfaces
Expand Down
5 changes: 5 additions & 0 deletions lib/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -982,6 +982,10 @@
'OCP\\Support\\Subscription\\IRegistry' => $baseDir . '/lib/public/Support/Subscription/IRegistry.php',
'OCP\\Support\\Subscription\\ISubscription' => $baseDir . '/lib/public/Support/Subscription/ISubscription.php',
'OCP\\Support\\Subscription\\ISupportedApps' => $baseDir . '/lib/public/Support/Subscription/ISupportedApps.php',
'OCP\\SystemReport\\ISystemReportManager' => $baseDir . '/lib/public/SystemReport/ISystemReportManager.php',
'OCP\\SystemReport\\ISystemReportSection' => $baseDir . '/lib/public/SystemReport/ISystemReportSection.php',
'OCP\\SystemReport\\SystemReportDetail' => $baseDir . '/lib/public/SystemReport/SystemReportDetail.php',
'OCP\\SystemReport\\SystemReportDetailFormat' => $baseDir . '/lib/public/SystemReport/SystemReportDetailFormat.php',
'OCP\\SystemTag\\Events\\AbstractTagEvent' => $baseDir . '/lib/public/SystemTag/Events/AbstractTagEvent.php',
'OCP\\SystemTag\\Events\\TagCreatedEvent' => $baseDir . '/lib/public/SystemTag/Events/TagCreatedEvent.php',
'OCP\\SystemTag\\Events\\TagDeletedEvent' => $baseDir . '/lib/public/SystemTag/Events/TagDeletedEvent.php',
Expand Down Expand Up @@ -2376,6 +2380,7 @@
'OC\\Support\\Subscription\\Assertion' => $baseDir . '/lib/private/Support/Subscription/Assertion.php',
'OC\\Support\\Subscription\\Registry' => $baseDir . '/lib/private/Support/Subscription/Registry.php',
'OC\\SystemConfig' => $baseDir . '/lib/private/SystemConfig.php',
'OC\\SystemReport\\SystemReportManager' => $baseDir . '/lib/private/SystemReport/SystemReportManager.php',
'OC\\SystemTag\\ManagerFactory' => $baseDir . '/lib/private/SystemTag/ManagerFactory.php',
'OC\\SystemTag\\SystemTag' => $baseDir . '/lib/private/SystemTag/SystemTag.php',
'OC\\SystemTag\\SystemTagManager' => $baseDir . '/lib/private/SystemTag/SystemTagManager.php',
Expand Down
5 changes: 5 additions & 0 deletions lib/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,10 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\Support\\Subscription\\IRegistry' => __DIR__ . '/../../..' . '/lib/public/Support/Subscription/IRegistry.php',
'OCP\\Support\\Subscription\\ISubscription' => __DIR__ . '/../../..' . '/lib/public/Support/Subscription/ISubscription.php',
'OCP\\Support\\Subscription\\ISupportedApps' => __DIR__ . '/../../..' . '/lib/public/Support/Subscription/ISupportedApps.php',
'OCP\\SystemReport\\ISystemReportManager' => __DIR__ . '/../../..' . '/lib/public/SystemReport/ISystemReportManager.php',
'OCP\\SystemReport\\ISystemReportSection' => __DIR__ . '/../../..' . '/lib/public/SystemReport/ISystemReportSection.php',
'OCP\\SystemReport\\SystemReportDetail' => __DIR__ . '/../../..' . '/lib/public/SystemReport/SystemReportDetail.php',
'OCP\\SystemReport\\SystemReportDetailFormat' => __DIR__ . '/../../..' . '/lib/public/SystemReport/SystemReportDetailFormat.php',
'OCP\\SystemTag\\Events\\AbstractTagEvent' => __DIR__ . '/../../..' . '/lib/public/SystemTag/Events/AbstractTagEvent.php',
'OCP\\SystemTag\\Events\\TagCreatedEvent' => __DIR__ . '/../../..' . '/lib/public/SystemTag/Events/TagCreatedEvent.php',
'OCP\\SystemTag\\Events\\TagDeletedEvent' => __DIR__ . '/../../..' . '/lib/public/SystemTag/Events/TagDeletedEvent.php',
Expand Down Expand Up @@ -2417,6 +2421,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Support\\Subscription\\Assertion' => __DIR__ . '/../../..' . '/lib/private/Support/Subscription/Assertion.php',
'OC\\Support\\Subscription\\Registry' => __DIR__ . '/../../..' . '/lib/private/Support/Subscription/Registry.php',
'OC\\SystemConfig' => __DIR__ . '/../../..' . '/lib/private/SystemConfig.php',
'OC\\SystemReport\\SystemReportManager' => __DIR__ . '/../../..' . '/lib/private/SystemReport/SystemReportManager.php',
'OC\\SystemTag\\ManagerFactory' => __DIR__ . '/../../..' . '/lib/private/SystemTag/ManagerFactory.php',
'OC\\SystemTag\\SystemTag' => __DIR__ . '/../../..' . '/lib/private/SystemTag/SystemTag.php',
'OC\\SystemTag\\SystemTagManager' => __DIR__ . '/../../..' . '/lib/private/SystemTag/SystemTagManager.php',
Expand Down
26 changes: 26 additions & 0 deletions lib/private/AppFramework/Bootstrap/RegistrationContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
use OCP\Share\IPublicShareTemplateProvider;
use OCP\SpeechToText\ISpeechToTextProvider;
use OCP\Support\CrashReport\IReporter;
use OCP\SystemReport\ISystemReportSection;
use OCP\Talk\ITalkBackend;
use OCP\TaskProcessing\ITaskType;
use OCP\Teams\ITeamResourceProvider;
Expand Down Expand Up @@ -144,6 +145,9 @@ class RegistrationContext {
/** @var ServiceRegistration<ISetupCheck>[] */
private array $setupChecks = [];

/** @var ServiceRegistration<ISystemReportSection>[] */
private array $systemReportSections = [];

/** @var PreviewProviderRegistration[] */
private array $previewProviders = [];

Expand Down Expand Up @@ -448,6 +452,14 @@ public function registerSetupCheck(string $setupCheckClass): void {
);
}

#[\Override]
public function registerSystemReportSection(string $sectionClass): void {
$this->context->registerSystemReportSection(
$this->appId,
$sectionClass
);
}

#[\Override]
public function registerDeclarativeSettings(string $declarativeSettingsClass): void {
$this->context->registerDeclarativeSettings(
Expand Down Expand Up @@ -678,6 +690,13 @@ public function registerSetupCheck(string $appId, string $setupCheckClass): void
$this->setupChecks[] = new ServiceRegistration($appId, $setupCheckClass);
}

/**
* @psalm-param class-string<ISystemReportSection> $sectionClass
*/
public function registerSystemReportSection(string $appId, string $sectionClass): void {
$this->systemReportSections[] = new ServiceRegistration($appId, $sectionClass);
}

/**
* @psalm-param class-string<IDeclarativeSettingsForm> $declarativeSettingsClass
*/
Expand Down Expand Up @@ -1055,6 +1074,13 @@ public function getSetupChecks(): array {
return $this->setupChecks;
}

/**
* @return ServiceRegistration<ISystemReportSection>[]
*/
public function getSystemReportSections(): array {
return $this->systemReportSections;
}

/**
* @return ServiceRegistration<ITeamResourceProvider>[]
*/
Expand Down
3 changes: 3 additions & 0 deletions lib/private/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@
use OC\Snowflake\SnowflakeGenerator;
use OC\SpeechToText\SpeechToTextManager;
use OC\Support\Subscription\Assertion;
use OC\SystemReport\SystemReportManager;
use OC\SystemTag\ManagerFactory as SystemTagManagerFactory;
use OC\Talk\Broker;
use OC\Teams\TeamManager;
Expand Down Expand Up @@ -280,6 +281,7 @@
use OCP\Snowflake\ISnowflakeGenerator;
use OCP\SpeechToText\ISpeechToTextManager;
use OCP\Support\Subscription\IAssertion;
use OCP\SystemReport\ISystemReportManager;
use OCP\SystemTag\ISystemTagManager;
use OCP\SystemTag\ISystemTagManagerFactory;
use OCP\SystemTag\ISystemTagObjectMapper;
Expand Down Expand Up @@ -1132,6 +1134,7 @@ function () use ($c) {
$this->registerDeprecatedAlias(IOCMProvider::class, OCMProvider::class);

$this->registerAlias(ISetupCheckManager::class, SetupCheckManager::class);
$this->registerAlias(ISystemReportManager::class, SystemReportManager::class);
$this->registerAlias(IProfileManager::class, ProfileManager::class);
$this->registerAlias(IAvailabilityCoordinator::class, AvailabilityCoordinator::class);
$this->registerAlias(IDeclarativeManager::class, DeclarativeManager::class);
Expand Down
51 changes: 51 additions & 0 deletions lib/private/SystemReport/SystemReportManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OC\SystemReport;

use OC\AppFramework\Bootstrap\Coordinator;
use OCP\SystemReport\ISystemReportManager;
use OCP\SystemReport\ISystemReportSection;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;

final readonly class SystemReportManager implements ISystemReportManager {
public function __construct(
private Coordinator $coordinator,
private ContainerInterface $container,
private LoggerInterface $logger,
) {
}

/**
* @return ISystemReportSection[]
*/
#[\Override]
public function getSections(): array {
$sections = [];
$registrations = $this->coordinator->getRegistrationContext()?->getSystemReportSections() ?? [];
foreach ($registrations as $registration) {
$class = $registration->getService();
try {
/** @var ISystemReportSection $section */
$section = $this->container->get($class);
// Trigger detail collection here so a failing section is skipped
// instead of surfacing later when the report is rendered.
$section->getDetails();
} catch (\Throwable $t) {
$this->logger->error('Exception while collecting system report section ' . $class . ': ' . $t->getMessage(), ['exception' => $t]);
continue;
}

$sections[] = $section;
}

return $sections;
}
}
9 changes: 9 additions & 0 deletions lib/public/AppFramework/Bootstrap/IRegistrationContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,15 @@ public function registerPublicShareTemplateProvider(string $class): void;
*/
public function registerSetupCheck(string $setupCheckClass): void;

/**
* Register an implementation of \OCP\SystemReport\ISystemReportSection that
* will contribute a section to the system report
*
* @param class-string<\OCP\SystemReport\ISystemReportSection> $sectionClass
* @since 36.0.0
*/
public function registerSystemReportSection(string $sectionClass): void;

/**
* Register an implementation of \OCP\Settings\IDeclarativeSettings that
* will handle the implementation of declarative settings
Expand Down
26 changes: 26 additions & 0 deletions lib/public/SystemReport/ISystemReportManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCP\SystemReport;

/**
* @since 36.0.0
*/
interface ISystemReportManager {
/**
* Resolve every registered \OCP\SystemReport\ISystemReportSection and
* return its contributed sections. A section whose resolution or
* getDetails() call throws is skipped and logged rather than aborting
* the whole report.
*
* @return ISystemReportSection[]
* @since 36.0.0
*/
public function getSections(): array;
}
41 changes: 41 additions & 0 deletions lib/public/SystemReport/ISystemReportSection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCP\SystemReport;

/**
* This interface needs to be implemented if you want to contribute a custom
* section to the system report that administrators can generate for support
* purposes. Register your implementation with
* \OCP\AppFramework\Bootstrap\IRegistrationContext::registerSystemReportSection().
*
* @since 36.0.0
*/
interface ISystemReportSection {
/**
* Unique, stable identifier of this section, e.g. "saml".
* Sections registered under the same id are merged.
*
* @since 36.0.0
*/
public function getId(): string;

/**
* Translated title shown as heading for this section in the report.
*
* @since 36.0.0
*/
public function getTitle(): string;

/**
* @return SystemReportDetail[]
* @since 36.0.0
*/
public function getDetails(): array;
}
Loading
Loading