diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 31d2fc6a21261..f2e6170416615 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -607,6 +607,7 @@ 'OCP\\IUserManager' => $baseDir . '/lib/public/IUserManager.php', 'OCP\\IUserSession' => $baseDir . '/lib/public/IUserSession.php', 'OCP\\Image' => $baseDir . '/lib/public/Image.php', + 'OCP\\Install\\Events\\InstallationCompletedEvent' => $baseDir . '/lib/public/Install/Events/InstallationCompletedEvent.php', 'OCP\\L10N\\IFactory' => $baseDir . '/lib/public/L10N/IFactory.php', 'OCP\\L10N\\ILanguageIterator' => $baseDir . '/lib/public/L10N/ILanguageIterator.php', 'OCP\\LDAP\\IDeletionFlagSupport' => $baseDir . '/lib/public/LDAP/IDeletionFlagSupport.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 6a2d0b10cd837..314e762fc83e5 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -656,6 +656,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OCP\\IUserManager' => __DIR__ . '/../../..' . '/lib/public/IUserManager.php', 'OCP\\IUserSession' => __DIR__ . '/../../..' . '/lib/public/IUserSession.php', 'OCP\\Image' => __DIR__ . '/../../..' . '/lib/public/Image.php', + 'OCP\\Install\\Events\\InstallationCompletedEvent' => __DIR__ . '/../../..' . '/lib/public/Install/Events/InstallationCompletedEvent.php', 'OCP\\L10N\\IFactory' => __DIR__ . '/../../..' . '/lib/public/L10N/IFactory.php', 'OCP\\L10N\\ILanguageIterator' => __DIR__ . '/../../..' . '/lib/public/L10N/ILanguageIterator.php', 'OCP\\LDAP\\IDeletionFlagSupport' => __DIR__ . '/../../..' . '/lib/public/LDAP/IDeletionFlagSupport.php', diff --git a/lib/private/Setup.php b/lib/private/Setup.php index b4102e73b5cf5..775731fbc8c51 100644 --- a/lib/private/Setup.php +++ b/lib/private/Setup.php @@ -22,11 +22,13 @@ use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\IJobList; use OCP\Defaults; +use OCP\EventDispatcher\IEventDispatcher; use OCP\IAppConfig; use OCP\IConfig; use OCP\IGroup; use OCP\IGroupManager; use OCP\IL10N; +use OCP\Install\Events\InstallationCompletedEvent; use OCP\IRequest; use OCP\IUserManager; use OCP\IUserSession; @@ -48,6 +50,7 @@ public function __construct( protected LoggerInterface $logger, protected ISecureRandom $random, protected Installer $installer, + protected IEventDispatcher $eventDispatcher, ) { $this->l10n = $l10nFactory->get('lib'); } @@ -408,6 +411,13 @@ public function install(array $options, ?IOutput $output = null): array { $user->setSystemEMailAddress($options['adminemail']); } + // Dispatch installation completed event + $adminUsername = !empty($username) ? $username : null; + $adminEmail = !empty($options['adminemail']) ? $options['adminemail'] : null; + $this->eventDispatcher->dispatchTyped( + new InstallationCompletedEvent($dataDir, $adminUsername, $adminEmail) + ); + return $error; } diff --git a/lib/public/Install/Events/InstallationCompletedEvent.php b/lib/public/Install/Events/InstallationCompletedEvent.php new file mode 100644 index 0000000000000..7cf75d76d6fce --- /dev/null +++ b/lib/public/Install/Events/InstallationCompletedEvent.php @@ -0,0 +1,79 @@ +dataDirectory; + } + + /** + * Get the admin username if an admin user was created + * + * @since 33.0.0 + */ + public function getAdminUsername(): ?string { + return $this->adminUsername; + } + + /** + * Get the admin email if configured + * + * @since 33.0.0 + */ + public function getAdminEmail(): ?string { + return $this->adminEmail; + } + + /** + * Check if an admin user was created during installation + * + * @since 33.0.0 + */ + public function hasAdminUser(): bool { + return $this->adminUsername !== null; + } +} diff --git a/tests/lib/Install/Events/InstallationCompletedEventTest.php b/tests/lib/Install/Events/InstallationCompletedEventTest.php new file mode 100644 index 0000000000000..3a973e008b90b --- /dev/null +++ b/tests/lib/Install/Events/InstallationCompletedEventTest.php @@ -0,0 +1,89 @@ +assertEquals($dataDir, $event->getDataDirectory()); + $this->assertEquals($adminUsername, $event->getAdminUsername()); + $this->assertEquals($adminEmail, $event->getAdminEmail()); + $this->assertTrue($event->hasAdminUser()); + } + + public function testConstructorWithMinimalParameters(): void { + $dataDir = '/path/to/data'; + + $event = new InstallationCompletedEvent($dataDir); + + $this->assertEquals($dataDir, $event->getDataDirectory()); + $this->assertNull($event->getAdminUsername()); + $this->assertNull($event->getAdminEmail()); + $this->assertFalse($event->hasAdminUser()); + } + + public function testConstructorWithUsernameOnly(): void { + $dataDir = '/path/to/data'; + $adminUsername = 'admin'; + + $event = new InstallationCompletedEvent($dataDir, $adminUsername); + + $this->assertEquals($dataDir, $event->getDataDirectory()); + $this->assertEquals($adminUsername, $event->getAdminUsername()); + $this->assertNull($event->getAdminEmail()); + $this->assertTrue($event->hasAdminUser()); + } + + public function testConstructorWithUsernameAndEmail(): void { + $dataDir = '/path/to/data'; + $adminUsername = 'admin'; + $adminEmail = 'admin@example.com'; + + $event = new InstallationCompletedEvent($dataDir, $adminUsername, $adminEmail); + + $this->assertEquals($dataDir, $event->getDataDirectory()); + $this->assertEquals($adminUsername, $event->getAdminUsername()); + $this->assertEquals($adminEmail, $event->getAdminEmail()); + $this->assertTrue($event->hasAdminUser()); + } + + public function testHasAdminUserReturnsFalseWhenUsernameIsNull(): void { + $event = new InstallationCompletedEvent('/path/to/data', null, 'admin@example.com'); + + $this->assertFalse($event->hasAdminUser()); + $this->assertNull($event->getAdminUsername()); + $this->assertEquals('admin@example.com', $event->getAdminEmail()); + } + + public function testDataDirectoryCanBeAnyString(): void { + $customPath = '/custom/data/directory'; + $event = new InstallationCompletedEvent($customPath); + + $this->assertEquals($customPath, $event->getDataDirectory()); + } + + public function testEmailCanBeSetWithoutUsername(): void { + $dataDir = '/path/to/data'; + $email = 'admin@example.com'; + + $event = new InstallationCompletedEvent($dataDir, null, $email); + + $this->assertNull($event->getAdminUsername()); + $this->assertEquals($email, $event->getAdminEmail()); + $this->assertFalse($event->hasAdminUser()); + } +} diff --git a/tests/lib/SetupTest.php b/tests/lib/SetupTest.php index b5e1b7000c339..5e7db440c0a48 100644 --- a/tests/lib/SetupTest.php +++ b/tests/lib/SetupTest.php @@ -12,6 +12,7 @@ use OC\Setup; use OC\SystemConfig; use OCP\Defaults; +use OCP\EventDispatcher\IEventDispatcher; use OCP\IL10N; use OCP\L10N\IFactory as IL10NFactory; use OCP\Security\ISecureRandom; @@ -27,6 +28,7 @@ class SetupTest extends \Test\TestCase { protected LoggerInterface $logger; protected ISecureRandom $random; protected Installer $installer; + protected IEventDispatcher $eventDispatcher; protected function setUp(): void { parent::setUp(); @@ -41,9 +43,10 @@ protected function setUp(): void { $this->logger = $this->createMock(LoggerInterface::class); $this->random = $this->createMock(ISecureRandom::class); $this->installer = $this->createMock(Installer::class); + $this->eventDispatcher = $this->createMock(IEventDispatcher::class); $this->setupClass = $this->getMockBuilder(Setup::class) ->setMethods(['class_exists', 'is_callable', 'getAvailableDbDriversForPdo']) - ->setConstructorArgs([$this->config, $this->iniWrapper, $this->l10nFactory, $this->defaults, $this->logger, $this->random, $this->installer]) + ->setConstructorArgs([$this->config, $this->iniWrapper, $this->l10nFactory, $this->defaults, $this->logger, $this->random, $this->installer, $this->eventDispatcher]) ->getMock(); }