Page MenuHomePhorge

D5030.1774840060.diff
No OneTemporary

Authored By
Unknown
Size
4 KB
Referenced Files
None
Subscribers
None

D5030.1774840060.diff

diff --git a/src/app/Console/Commands/User/PurgeCommand.php b/src/app/Console/Commands/User/PurgeCommand.php
new file mode 100644
--- /dev/null
+++ b/src/app/Console/Commands/User/PurgeCommand.php
@@ -0,0 +1,117 @@
+<?php
+
+namespace App\Console\Commands\User;
+
+use App\Console\Command;
+use App\User;
+use Illuminate\Database\Eloquent\Builder;
+
+class PurgeCommand extends Command
+{
+ /**
+ * The name and signature of the console command.
+ *
+ * @var string
+ */
+ protected $signature = 'user:purge {--dry-run} {--min-age=2y} {--limit=} {--confirm}';
+
+ /**
+ * The console command description.
+ *
+ * @var string
+ */
+ protected $description = 'Delete users that are inactive';
+
+
+ private function parseAge($age)
+ {
+ if (preg_match('/^([0-9]+)([mdy])$/i', $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);
+ }
+ return $date;
+ }
+ return null;
+ }
+
+ /**
+ * Execute the console command.
+ *
+ * @return mixed
+ */
+ public function handle()
+ {
+ $dry_run = $this->option('dry-run');
+ $min_age = $this->option('min-age');
+ $limit = $this->option('limit');
+ $confirm = $this->option('confirm');
+
+ if (!$confirm && !$dry_run) {
+ $this->error("WARNING: THIS COMMAND WILL DELETE USERS, are you sure? Run with --confirm if you are.");
+ exit(1);
+ }
+
+// select count(*) from users
+// left join oauth_access_tokens on oauth_access_tokens.user_id = users.id
+// left join policy_ratelimit on policy_ratelimit.user_id = users.id
+// left join roundcube_prod.users AS rcusers on rcusers.username = users.email
+// where status & 64
+// and users.updated_at < DATE_SUB(NOW(), INTERVAL 2 YEAR)
+// and deleted_at is null
+// and oauth_access_tokens.id is null
+// and (policy_ratelimit.created_at < DATE_SUB(NOW(), INTERVAL 2 YEAR) or policy_ratelimit.id is null)
+// and (rcusers.last_login < DATE_SUB(NOW(), INTERVAL 2 YEAR) or rcusers.username is null);
+
+ $date = $this->parseAge($min_age);
+ if (!$date) {
+ $this->error("Invalid --min-age.");
+ return 1;
+ }
+
+ // Find inactive users by checking:
+ // * the account is degraded
+ // * there is no active oauth token
+ // * there is no recent policy_ratelimit entry for the user
+ // * there is no recent roundcube login for the user
+ $users = User::select('users.id', 'users.email')
+ ->leftJoin('oauth_access_tokens', 'oauth_access_tokens.user_id', '=', 'users.id')
+ ->leftJoin('policy_ratelimit', 'policy_ratelimit.user_id', '=', 'users.id')
+ ->leftJoin('roundcube_prod.users as rcusers', 'rcusers.username', '=', 'users.email')
+ ->where('users.status', '&', User::STATUS_DEGRADED)
+ ->whereNull('oauth_access_tokens.id')
+ ->where(function (Builder $query) use ($date) {
+ $query->where('policy_ratelimit.created_at', '<=', $date)
+ ->orWhereNull('policy_ratelimit.id');
+ })
+ ->where(function (Builder $query) use ($date) {
+ $query->where('rcusers.last_login', '<=', $date)
+ ->orWhereNull('rcusers.username');
+ });
+
+ if ($limit > 0) {
+ $users->limit($limit);
+ }
+
+ $users = $users->orderBy('id')->cursor();
+
+ $count = 0;
+ foreach ($users as $user) {
+ $count++;
+ if ($dry_run) {
+ $this->info("{$user->email}: will be deleted");
+ } else {
+ \App\Jobs\User\DeleteJob::dispatch($user->id);
+ $this->info("{$user->email}: pushed");
+ }
+ }
+ $this->info("A total of $count users will be deleted");
+ }
+}

File Metadata

Mime Type
text/plain
Expires
Mon, Mar 30, 3:07 AM (2 d, 22 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18790398
Default Alt Text
D5030.1774840060.diff (4 KB)

Event Timeline