Page MenuHomePhorge

D5040.1774856320.diff
No OneTemporary

Authored By
Unknown
Size
11 KB
Referenced Files
None
Subscribers
None

D5040.1774856320.diff

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
@@ -12,7 +12,7 @@
*
* @var string
*/
- protected $signature = 'user:resync {user?} {--deleted-only} {--dry-run} {--min-age=} {--limit=}';
+ protected $signature = 'user:resync {user?} {--deleted-only} {--created-only} {--dry-run} {--min-age=} {--limit=}';
/**
* The console command description.
@@ -30,110 +30,139 @@
{
$user = $this->argument('user');
$deleted_only = $this->option('deleted-only');
+ $created_only = $this->option('created-only');
$dry_run = $this->option('dry-run');
$min_age = $this->option('min-age');
$limit = $this->option('limit');
$with_ldap = \config('app.with_ldap');
+ $req_user = null;
+ $createdUsers = null;
+ $deletedUsers = null;
if (!empty($user)) {
if ($req_user = $this->getUser($user, true)) {
- $users = [$req_user];
+ // $this->error("req user {$req_user}.");
+ $deletedUsers = User::onlyTrashed()->where('id', $req_user->id);
+ $createdUsers = User::where('id', $req_user->id);
} else {
$this->error("User not found.");
return 1;
}
} else {
- $users = User::withTrashed();
-
- if ($deleted_only) {
- $users->whereNotNull('deleted_at')
- ->where(function ($query) {
- $query->where('status', '&', User::STATUS_IMAP_READY)
- ->orWhere('status', '&', User::STATUS_LDAP_READY);
- });
+ if (!$created_only) {
+ $deletedUsers = User::onlyTrashed();
}
+ if (!$deleted_only) {
+ $createdUsers = User::withoutTrashed();
+ }
+ }
+
+ if ($deletedUsers) {
+ $deletedUsers = $deletedUsers->where(function ($query) use ($with_ldap) {
+ $query = $query->where('status', '&', User::STATUS_IMAP_READY);
+ if ($with_ldap) {
+ $query->orWhere('status', '&', User::STATUS_LDAP_READY);
+ }
+ });
+ }
+
+ if ($createdUsers) {
+ $createdUsers = $createdUsers->where(function ($query) use ($with_ldap) {
+ $query = $query->whereNot('status', '&', User::STATUS_IMAP_READY)
+ ->orWhereNot('status', '&', User::STATUS_ACTIVE);
+ if ($with_ldap) {
+ $query->orWhereNot('status', '&', User::STATUS_LDAP_READY);
+ }
+ });
+ }
+
+ if ($min_age) {
+ if (preg_match('/^([0-9]+)([mdy])$/i', $min_age, $matches)) {
+ $count = (int) $matches[1];
+ $period = strtolower($matches[2]);
+ $date = \Carbon\Carbon::now();
- if ($min_age) {
- if (preg_match('/^([0-9]+)([mdy])$/i', $min_age, $matches)) {
- $count = (int) $matches[1];
- $period = strtolower($matches[2]);
- $date = \Carbon\Carbon::now();
-
- if ($period == 'y') {
- $date->subYearsWithoutOverflow($count);
- } elseif ($period == 'm') {
- $date->subMonthsWithoutOverflow($count);
- } else {
- $date->subDays($count);
- }
- $users = $users->where('deleted_at', '<=', $date);
+ if ($period == 'y') {
+ $date->subYearsWithoutOverflow($count);
+ } elseif ($period == 'm') {
+ $date->subMonthsWithoutOverflow($count);
} else {
- $this->error("Invalid --min-age.");
- return 1;
+ $date->subDays($count);
}
+ if ($createdUsers) {
+ $createdUsers = $createdUsers->where('created_at', '<=', $date);
+ }
+ if ($deletedUsers) {
+ $deletedUsers = $deletedUsers->where('deleted_at', '<=', $date);
+ }
+ } else {
+ $this->error("Invalid --min-age.");
+ return 1;
}
-
- $users = $users->orderBy('id')->cursor();
}
// TODO: Maybe we should also have account:resync, domain:resync, resource:resync and so on.
$count = 0;
- foreach ($users as $user) {
- if ($limit > 0 && $count > $limit) {
- $this->info("Reached limit of $limit");
- break;
+
+ // Push create jobs for users that should be created, but aren't fully
+ if ($createdUsers) {
+ $createdUsers = $createdUsers->orderBy('id')->cursor();
+ foreach ($createdUsers as $user) {
+ if ($limit > 0 && $count > $limit) {
+ $this->info("Reached limit of $limit");
+ break;
+ }
+
+ $count++;
+ if ($dry_run) {
+ $this->info("{$user->email}: will be pushed");
+ continue;
+ }
+
+ \App\Jobs\User\CreateJob::dispatch($user->id);
+ $this->info("{$user->email}: pushed (create)");
}
- if ($user->trashed()) {
- if (($with_ldap && $user->isLdapReady()) || $user->isImapReady()) {
- $count++;
- if ($dry_run) {
- $this->info("{$user->email}: will be pushed");
- continue;
- }
-
- if ($user->isDeleted()) {
- // Remove the DELETED flag so the DeleteJob can do the work
- $user->timestamps = false;
- $user->update(['status' => $user->status ^ User::STATUS_DELETED]);
- }
-
- // TODO: Do this not asyncronously as an option or when a signle user is requested?
- \App\Jobs\User\DeleteJob::dispatch($user->id);
-
- $this->info("{$user->email}: pushed");
- } else {
- // User properly deleted, no need to push.
- // Here potentially we could connect to ldap/imap backend and check to be sure
- // that the user is really deleted no matter what status it has in the database.
+ }
- $this->info("{$user->email}: in-sync");
+ // Push delete jobs for users that should be deleted, but aren't fully
+ if ($deletedUsers) {
+ $deletedUsers = $deletedUsers->orderBy('id')->cursor();
+ foreach ($deletedUsers as $user) {
+ if ($limit > 0 && $count > $limit) {
+ $this->info("Reached limit of $limit");
+ break;
}
- } else {
- if (!$user->isActive() || ($with_ldap && !$user->isLdapReady()) || !$user->isImapReady()) {
- $count++;
- if ($dry_run) {
- $this->info("{$user->email}: will be pushed");
- continue;
- }
-
- \App\Jobs\User\CreateJob::dispatch($user->id);
-
- $this->info("{$user->email}: pushed");
- } elseif (!empty($req_user)) {
- $count++;
- if ($dry_run) {
- $this->info("{$user->email}: will be pushed");
- continue;
- }
- // 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
- \App\Jobs\User\ResyncJob::dispatch($user->id);
+ $count++;
+ if ($dry_run) {
+ $this->info("{$user->email}: will be pushed");
+ continue;
+ }
- $this->info("{$user->email}: pushed");
+ if ($user->isDeleted()) {
+ // Remove the DELETED flag so the DeleteJob can do the work
+ $user->timestamps = false;
+ $user->update(['status' => $user->status ^ User::STATUS_DELETED]);
+ }
+
+ \App\Jobs\User\DeleteJob::dispatch($user->id);
+ $this->info("{$user->email}: pushed (delete)");
+ }
+ }
+
+ // Push a resync job if none of the above matched and we requested a specific user
+ if ($req_user && $count == 0) {
+ if ($dry_run) {
+ $this->info("{$req_user->email}: will be pushed");
+ } else {
+ if ($req_user->trashed()) {
+ $this->info("{$req_user->email}: in-sync");
} else {
- $this->info("{$user->email}: in-sync");
+ // 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
+ \App\Jobs\User\ResyncJob::dispatch($req_user->id);
+ $this->info("{$req_user->email}: pushed (resync)");
}
}
}
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
@@ -16,6 +16,7 @@
parent::setUp();
$this->deleteTestUser('user@force-delete.com');
+ $this->deleteTestUser('user@incomplete.com');
}
/**
@@ -24,6 +25,7 @@
public function tearDown(): void
{
$this->deleteTestUser('user@force-delete.com');
+ $this->deleteTestUser('user@incomplete.com');
parent::tearDown();
}
@@ -63,7 +65,7 @@
$output = trim(\Artisan::output());
$this->assertSame(0, $code);
- $this->assertSame("{$user->email}: pushed", $output);
+ $this->assertSame("{$user->email}: pushed (delete)", $output);
$user->refresh();
$this->assertFalse($user->isDeleted());
$this->assertTrue($user->isImapReady());
@@ -83,6 +85,7 @@
$this->assertSame(0, $code);
$this->assertSame("{$user->email}: in-sync", $output);
+
Queue::assertNothingPushed();
Queue::fake();
@@ -98,7 +101,7 @@
$output = trim(\Artisan::output());
$this->assertSame(0, $code);
- $this->assertSame("{$user->email}: pushed", $output);
+ $this->assertSame("{$user->email}: pushed (delete)", $output);
}
/**
@@ -117,7 +120,7 @@
$output = trim(\Artisan::output());
$this->assertSame(0, $code);
- $this->assertSame("{$user->email}: pushed", $output);
+ $this->assertSame("{$user->email}: pushed (resync)", $output);
Queue::assertPushed(\App\Jobs\User\ResyncJob::class, 1);
Queue::assertPushed(\App\Jobs\User\ResyncJob::class, function ($job) use ($user) {
@@ -125,6 +128,15 @@
return $job_user_id === $user->id;
});
+ // Test a user that is not IMAP_READY
+ $user = $this->getTestUser('user@incomplete.com', [
+ 'status' => User::STATUS_LDAP_READY | User::STATUS_ACTIVE,
+ ]);
+ $code = \Artisan::call("user:resync --created-only");
+ $output = trim(\Artisan::output());
+
+ $this->assertSame(0, $code);
+ $this->assertStringContainsString("{$user->email}: pushed (create)", $output);
// TODO: Test other cases
}
}

File Metadata

Mime Type
text/plain
Expires
Mon, Mar 30, 7:38 AM (4 d, 13 m ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18797301
Default Alt Text
D5040.1774856320.diff (11 KB)

Event Timeline