diff --git a/src/app/Console/Commands/User/CreateCommand.php b/src/app/Console/Commands/User/CreateCommand.php new file mode 100644 --- /dev/null +++ b/src/app/Console/Commands/User/CreateCommand.php @@ -0,0 +1,97 @@ +argument('email'); + $packages = $this->option('package'); + $password = $this->option('password'); + $role = $this->option('role'); + + list($local, $domainName) = explode('@', $email, 2); + + $domain = $this->getDomain($domainName); + + if (!$domain) { + $this->error("No such domain {$domainName}."); + return 1; + } + + if ($domain->isPublic()) { + $this->error("Domain {$domainName} is public."); + return 1; + } + + $owner = $domain->wallet()->owner; + $existingUser = null; + + // Validate email address + if ($error = UsersController::validateEmail($email, $owner, $existingUser)) { + $this->error("{$email}: {$error}"); + return 1; + } + + if ($existingUser) { + $this->info("The user with the email: {$email} exists already"); + return 0; + } + + DB::beginTransaction(); + + if ($existingUser) { + $this->info("Force deleting existing but deleted user {$email}"); + $existingUser->forceDelete(); + } + + if (!$password) { + $password = \App\Utils::generatePassphrase(); + } + + $user = \App\User::create( + [ + 'email' => $email, + 'password' => $password + ] + ); + $user->role = $role; + $user->save(); + + foreach ($packages as $package) { + $userPackage = $this->getObject(\App\Package::class, $package, 'title', false); + if (!$userPackage) { + $this->error("Invalid package: {$package}"); + return 1; + } + $user->assignPackage($userPackage); + } + + DB::commit(); + + $this->info($user->id); + } +} diff --git a/src/tests/Feature/Console/User/CreateTest.php b/src/tests/Feature/Console/User/CreateTest.php new file mode 100644 --- /dev/null +++ b/src/tests/Feature/Console/User/CreateTest.php @@ -0,0 +1,76 @@ +deleteTestUser('user@kolab.org'); + $this->deleteTestUser('admin@kolab.org'); + } + + /** + * {@inheritDoc} + */ + public function tearDown(): void + { + $this->deleteTestUser('user@kolab.org'); + $this->deleteTestUser('admin@kolab.org'); + + parent::tearDown(); + } + + /** + * Test the command + */ + public function testHandle(): void + { + Queue::fake(); + + // Warning: We're not using artisan() here, as this will not + // allow us to test "empty output" cases + + // Existing email + $code = \Artisan::call("user:create jack@kolab.org"); + $output = trim(\Artisan::output()); + $this->assertSame(1, $code); + $this->assertSame("jack@kolab.org: The specified email is not available.", $output); + + // Existing email (of a user alias) + $code = \Artisan::call("user:create jack.daniels@kolab.org"); + $output = trim(\Artisan::output()); + $this->assertSame(1, $code); + $this->assertSame("jack.daniels@kolab.org: The specified email is not available.", $output); + + // Public domain not allowed in the group email address + $code = \Artisan::call("user:create user@kolabnow.com"); + $output = trim(\Artisan::output()); + $this->assertSame(1, $code); + $this->assertSame("Domain kolabnow.com is public.", $output); + + // Valid + $code = \Artisan::call("user:create user@kolab.org"); + $output = trim(\Artisan::output()); + $user = User::where('email', 'user@kolab.org')->first(); + $this->assertSame(0, $code); + $this->assertEquals($user->id, $output); + + // Valid + $code = \Artisan::call("user:create admin@kolab.org --package=kolab --role=admin --password=simple123"); + $output = trim(\Artisan::output()); + $user = User::where('email', 'admin@kolab.org')->first(); + $this->assertSame(0, $code); + $this->assertEquals($user->id, $output); + $this->assertEquals($user->role, "admin"); + } +}