diff --git a/src/app/Console/Commands/User/ResyncCommand.php b/src/app/Console/Commands/User/ResyncCommand.php --- a/src/app/Console/Commands/User/ResyncCommand.php +++ b/src/app/Console/Commands/User/ResyncCommand.php @@ -2,10 +2,7 @@ namespace App\Console\Commands\User; -use App\Backends\IMAP; -use App\Backends\LDAP; use App\Console\Command; -use App\Domain; use App\User; class ResyncCommand extends Command @@ -100,37 +97,9 @@ continue; } - $job = \App\Jobs\User\UpdateJob::class; - - // Make sure the LDAP entry exists, fix that - if ($with_ldap && $user->isLdapReady()) { - // Check (and fix) the custom domain state - $domain = $user->domain(); - if (!$domain->isPublic() && !LDAP::getDomain($domain->namespace)) { - $domain->status &= ~Domain::STATUS_LDAP_READY; - $domain->save(); - \App\Jobs\Domain\CreateJob::dispatch($domain->id); - } - - if (!LDAP::getUser($user->email)) { - $user->status &= ~User::STATUS_LDAP_READY; - $job = \App\Jobs\User\CreateJob::class; - } - } - - // Make sure the IMAP mailbox exists - if ($user->isImapReady()) { - if (!IMAP::verifyAccount($user->email)) { - $user->status &= ~User::STATUS_IMAP_READY; - $job = \App\Jobs\User\CreateJob::class; - } - } - - $user->update(); - // We push the update only if a specific user is requested, // We don't want to flood the database/backend with an update of all users - $job::dispatch($user->id); + \App\Jobs\User\ResyncJob::dispatch($user->id); $this->info("{$user->email}: pushed"); } else { diff --git a/src/app/Jobs/User/ResyncJob.php b/src/app/Jobs/User/ResyncJob.php new file mode 100644 --- /dev/null +++ b/src/app/Jobs/User/ResyncJob.php @@ -0,0 +1,66 @@ +getUser(); + + if (!$user) { + return; + } + + if ($user->role) { + // Admins/resellers don't reside in LDAP (for now) + return; + } + + $withLdap = \config('app.with_ldap'); + + $userJob = \App\Jobs\User\UpdateJob::class; + + // Make sure the LDAP entry exists, fix that + if ($withLdap && $user->isLdapReady()) { + // Check (and fix) the custom domain state + $domain = $user->domain(); + if (!$domain->isPublic() && !LDAP::getDomain($domain->namespace)) { + $domain->status &= ~Domain::STATUS_LDAP_READY; + $domain->save(); + + $job = new \App\Jobs\Domain\CreateJob($domain->id); + $job->handle(); + } + + if (!LDAP::getUser($user->email)) { + $user->status &= ~User::STATUS_LDAP_READY; + $userJob = \App\Jobs\User\CreateJob::class; + } + } + + // Make sure the IMAP mailbox exists too + if ($user->isImapReady()) { + if (!IMAP::verifyAccount($user->email)) { + $user->status &= ~User::STATUS_IMAP_READY; + $userJob = \App\Jobs\User\CreateJob::class; + } + } + + $user->update(); + + $job = new $userJob($user->id); + $job->handle(); + } +} diff --git a/src/tests/Feature/Console/User/ResyncTest.php b/src/tests/Feature/Console/User/ResyncTest.php --- a/src/tests/Feature/Console/User/ResyncTest.php +++ b/src/tests/Feature/Console/User/ResyncTest.php @@ -2,7 +2,6 @@ namespace Tests\Feature\Console\User; -use App\Domain; use App\User; use Illuminate\Support\Facades\Queue; use Tests\TestCase; @@ -17,7 +16,6 @@ parent::setUp(); $this->deleteTestUser('user@force-delete.com'); - $this->deleteTestDomain('force-delete.com'); } /** @@ -26,7 +24,6 @@ public function tearDown(): void { $this->deleteTestUser('user@force-delete.com'); - $this->deleteTestDomain('force-delete.com'); parent::tearDown(); } @@ -106,45 +103,27 @@ /** * Test the command (existing users) - * - * @group ldap - * @group imap */ public function testHandleExisting(): void { - $domain = $this->getTestDomain('force-delete.com', [ - 'status' => Domain::STATUS_LDAP_READY | Domain::STATUS_ACTIVE, - 'type' => Domain::TYPE_EXTERNAL, - ]); - $user = $this->getTestUser('user@force-delete.com', [ 'status' => User::STATUS_LDAP_READY | User::STATUS_IMAP_READY | User::STATUS_ACTIVE, ]); Queue::fake(); - // Test a user (and custom domain) that both aren't in ldap (despite their status) + // Test a specific user $code = \Artisan::call("user:resync {$user->email}"); $output = trim(\Artisan::output()); $this->assertSame(0, $code); $this->assertSame("{$user->email}: pushed", $output); - $user->refresh(); - $domain->refresh(); - $this->assertFalse($user->isLdapReady()); - $this->assertFalse($user->isImapReady()); - $this->assertFalse($domain->isLdapReady()); - Queue::assertPushed(\App\Jobs\User\CreateJob::class, 1); - Queue::assertPushed(\App\Jobs\User\CreateJob::class, function ($job) use ($user) { + Queue::assertPushed(\App\Jobs\User\ResyncJob::class, 1); + Queue::assertPushed(\App\Jobs\User\ResyncJob::class, function ($job) use ($user) { $job_user_id = TestCase::getObjectProperty($job, 'userId'); return $job_user_id === $user->id; }); - Queue::assertPushed(\App\Jobs\Domain\CreateJob::class, 1); - Queue::assertPushed(\App\Jobs\Domain\CreateJob::class, function ($job) use ($domain) { - $job_domain_id = TestCase::getObjectProperty($job, 'domainId'); - return $job_domain_id === $domain->id; - }); // TODO: Test other cases } diff --git a/src/tests/Feature/Jobs/User/CreateTest.php b/src/tests/Feature/Jobs/User/CreateTest.php --- a/src/tests/Feature/Jobs/User/CreateTest.php +++ b/src/tests/Feature/Jobs/User/CreateTest.php @@ -39,6 +39,10 @@ $domain->status |= \App\Domain::STATUS_LDAP_READY; $domain->save(); + // TODO: Make the test working with various with_imap/with_ldap combinations + \config(['app.with_imap' => true]); + \config(['app.with_ldap' => true]); + $this->assertFalse($user->isLdapReady()); $this->assertFalse($user->isImapReady()); $this->assertFalse($user->isActive()); diff --git a/src/tests/Feature/Jobs/User/DeleteTest.php b/src/tests/Feature/Jobs/User/DeleteTest.php --- a/src/tests/Feature/Jobs/User/DeleteTest.php +++ b/src/tests/Feature/Jobs/User/DeleteTest.php @@ -55,7 +55,7 @@ $user->refresh(); $this->assertSame(\config('app.with_ldap'), $user->isLdapReady()); - $this->assertTrue($user->isImapReady()); + $this->assertSame(\config('app.with_imap'), $user->isImapReady()); $this->assertFalse($user->isDeleted()); $this->assertNotNull($rcdb->table('users')->where('username', $user->email)->first()); diff --git a/src/tests/Feature/Jobs/User/ResyncTest.php b/src/tests/Feature/Jobs/User/ResyncTest.php new file mode 100644 --- /dev/null +++ b/src/tests/Feature/Jobs/User/ResyncTest.php @@ -0,0 +1,77 @@ +deleteTestUser('user@resync-job.com'); + $this->deleteTestDomain('resync-job.com'); + } + + /** + * {@inheritDoc} + */ + public function tearDown(): void + { + $this->deleteTestUser('user@resync-job.com'); + $this->deleteTestDomain('resync-job.com'); + + parent::tearDown(); + } + + /** + * Test the job execution + * + * @group ldap + * @group imap + */ + public function testHandle(): void + { + $domain = $this->getTestDomain('resync-job.com', [ + 'status' => Domain::STATUS_LDAP_READY | Domain::STATUS_ACTIVE, + 'type' => Domain::TYPE_EXTERNAL, + ]); + + $user = $this->getTestUser('user@resync-job.com', [ + 'status' => User::STATUS_LDAP_READY | User::STATUS_IMAP_READY | User::STATUS_ACTIVE, + ]); + + // TODO: Make the test working with various with_imap/with_ldap combinations + \config(['app.with_imap' => true]); + \config(['app.with_ldap' => true]); + + $this->assertTrue(empty(LDAP::getDomain($domain->namespace))); + $this->assertTrue(empty(LDAP::getUser($user->email))); + + // Test a user (and custom domain) that both aren't in ldap (despite their status) + $job = new \App\Jobs\User\ResyncJob($user->id); + $job->handle(); + + $user->refresh(); + $domain->refresh(); + + $this->assertTrue($user->isLdapReady()); + $this->assertTrue($user->isImapReady()); + $this->assertTrue($domain->isLdapReady()); + + $this->assertTrue(!empty(LDAP::getDomain($domain->namespace))); + $this->assertTrue(!empty(LDAP::getUser($user->email))); + $this->assertTrue(IMAP::verifyAccount($user->email)); + + // TODO: More tests cases + } +}