From 5bb1632ef838d814b2739b54e83a6b7a35662147 Mon Sep 17 00:00:00 2001 From: Craig Heydenburg Date: Tue, 24 Mar 2020 14:45:13 -0400 Subject: [PATCH 1/2] add command to generate any number of users. closes #4160 --- CHANGELOG-3.0.md | 1 + docs/AccessControl/Users/GenerateUsers.md | 24 ++ docs/AccessControl/Users/README.md | 4 + .../Command/GenerateTestUsersCommand.php | 221 ++++++++++++++++++ 4 files changed, 250 insertions(+) create mode 100644 docs/AccessControl/Users/GenerateUsers.md create mode 100644 src/Zikula/CoreBundle/Command/GenerateTestUsersCommand.php diff --git a/CHANGELOG-3.0.md b/CHANGELOG-3.0.md index 4cad75c6af..b592295412 100644 --- a/CHANGELOG-3.0.md +++ b/CHANGELOG-3.0.md @@ -220,6 +220,7 @@ - Added display of authentication method to user list (#3704). - Added UserCreationApi to assist with the manual creation of ZAuth-method users (#3265). - Added CLI Command to import users `bin/console zikula:users:import`. + - Added CLI Command to create any number of users for testing purposes `bin/console zikula:users:generate`. - Vendor updates: - antishov/doctrine-extensions-bundle updated from 1.2.2 to 1.4.2 diff --git a/docs/AccessControl/Users/GenerateUsers.md b/docs/AccessControl/Users/GenerateUsers.md new file mode 100644 index 0000000000..f3608cc97e --- /dev/null +++ b/docs/AccessControl/Users/GenerateUsers.md @@ -0,0 +1,24 @@ +--- +currentMenu: users +--- +# Generate Users + +You can generate any number of users by using the CLI command below: + +## Via CLI + + bin/console zikula:users:generate + +### Options + + - `--active=[0|1|2]` + - `0` all users inactive + - `1` all users active + - `2` random assignment per user (`0|1`) + - `--verified=[0|1|2]` + - `0` all user emails unverified + - `1` all user emails verified + - `2` random assignment per user (`0|1`) + + + bin/console zikula:users:generate --active=0 --verified=2 diff --git a/docs/AccessControl/Users/README.md b/docs/AccessControl/Users/README.md index 11a1dfd2cc..614a7b280d 100644 --- a/docs/AccessControl/Users/README.md +++ b/docs/AccessControl/Users/README.md @@ -45,6 +45,10 @@ TBD - [Importing Users](ImportFromFile.md) +## Generate users + +- [Generate users for test purposes](GenerateUsers.md) + ## For developers - [CurrentUserApi](Dev/CurrentUserApi.md) diff --git a/src/Zikula/CoreBundle/Command/GenerateTestUsersCommand.php b/src/Zikula/CoreBundle/Command/GenerateTestUsersCommand.php new file mode 100644 index 0000000000..88191b3a9c --- /dev/null +++ b/src/Zikula/CoreBundle/Command/GenerateTestUsersCommand.php @@ -0,0 +1,221 @@ +conn = $connection; + $utcTZ = new \DateTimeZone('UTC'); + $this->nowUTC = new \DateTime('now', $utcTZ); + $this->startUTC = new \DateTime('1970-01-01 00:00:00', $utcTZ); + } + + protected function configure() + { + $this + ->setDefinition([ + new InputArgument('amount', InputArgument::REQUIRED, 'The number of users to create'), + ]) + ->addOption( + 'active', + null, + InputOption::VALUE_REQUIRED, + 'All the users are 1=active, 0=inactive, 2=random choice 0|1', + UsersConstant::ACTIVATED_ACTIVE + ) + ->addOption( + 'verified', + null, + InputOption::VALUE_REQUIRED, + 'All the user emails marked as 1=verified, 0=unverified, 2=random choice 0|1', + 1 + ) + ->setDescription('Generates users for testing purposes') + ->setHelp( + <<<'EOT' +The %command.name% command generates users in order to fill a database for testing purposes. +These users will not be able to login. The users are placed into a newly created group, not the standard users group. + +php %command.full_name% 1000 + +This will generate 1000 randomly named users using all the default values. + +Options: +--active (-a) 0|1|2 (default: 1) 1=all users active, 0=all users inactive, 2=random assignment 0|1 + +--verified (-v) 0|1|2 (default: 1) 1=all user emails verified, 0=all user emails unverified, 2=random assignment 0|1 + +php %command.full_name% 1000 --active=0 --verified=2 + +EOT + ); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + $amount = (int) abs($input->getArgument('amount')); + $key = bin2hex(random_bytes(3)); + $groupId = $this->createGroup($key); + $divisor = (int) ceil($amount / 100); + $this->active = in_array((int) $input->getOption('active'), [0, 1, 2]) ? (int) $input->getOption('active') : UsersConstant::ACTIVATED_ACTIVE; + $this->verified = in_array((int) $input->getOption('verified'), [0, 1, 2]) ? (int) $input->getOption('verified') : 1; + + $io->title('User generation utility'); + $io->text('Generating users...'); + $io->progressStart($amount); + + for ($i = 1; $i <= $amount; $i++) { + $uname = 'user' . $key . $i; + $this->insertUser($uname); + $uid = (int) $this->conn->lastInsertId(); + $this->insertAttributes($uid); + $this->insertMapping($uid, $uname); + $this->insertGroup($uid, $groupId); + if (0 === $i % $divisor) { + $io->progressAdvance((int) ceil($amount / $divisor)); + } + } + + $io->progressFinish(); + $io->success('User generation complete!'); + $io->text(sprintf('%d users created (group name: group%s).', $amount, $key)); + + return 0; + } + + private function insertUser(string $uname): void + { + $types = [\PDO::PARAM_STR, \PDO::PARAM_STR, \PDO::PARAM_INT, 'datetime', \PDO::PARAM_INT, 'datetime', 'datetime', \PDO::PARAM_STR, \PDO::PARAM_STR]; + try { + $this->conn->insert('users', [ + 'uname' => $uname, + 'email' => $uname . '@example.com', + 'activated' => 2 === $this->active ? random_int(0, 1) : $this->active, + 'approved_date' => $this->nowUTC, + 'approved_by' => 2, + 'user_regdate' => $this->nowUTC, + 'lastlogin' => $this->startUTC, + 'tz' => '', + 'locale' => '' + ], $types); + } catch (DBALException $exception) { + // do nothing? + } + } + + private function insertAttributes(int $uid): void + { + $types = [\PDO::PARAM_STR, \PDO::PARAM_INT, \PDO::PARAM_STR]; + try { + $this->conn->insert('users_attributes', [ + 'name' => UsersConstant::AUTHENTICATION_METHOD_ATTRIBUTE_KEY, + 'user_id' => $uid, + 'value' => ZAuthConstant::AUTHENTICATION_METHOD_EITHER, + ], $types); + } catch (DBALException $exception) { + // do nothing? + } + } + + private function insertMapping(int $uid, string $uname): void + { + $types = [\PDO::PARAM_STR, \PDO::PARAM_INT, \PDO::PARAM_STR, \PDO::PARAM_STR, \PDO::PARAM_INT, \PDO::PARAM_STR]; + try { + $this->conn->insert('zauth_authentication_mapping', [ + 'method' => ZAuthConstant::AUTHENTICATION_METHOD_EITHER, + 'uid' => $uid, + 'uname' => $uname, + 'email' => $uname . '@example.com', + 'verifiedEmail' => 2 === $this->verified ? random_int(0, 1) : $this->verified, + 'pass' => '', + ], $types); + } catch (DBALException $exception) { + // do nothing? + } + } + + private function createGroup(string $key): int + { + $types = [\PDO::PARAM_STR, \PDO::PARAM_INT, \PDO::PARAM_STR, \PDO::PARAM_INT, \PDO::PARAM_INT]; + try { + $this->conn->insert('groups', [ + 'name' => 'group' . $key, + 'gtype' => 0, + 'description' => 'temp group for testing', + 'state' => 0, + 'nbumax' => 0, + ], $types); + } catch (DBALException $exception) { + // do nothing? + } + + return (int) $this->conn->lastInsertId(); + } + + private function insertGroup(int $uid, int $gid) : void + { + $types = [\PDO::PARAM_INT, \PDO::PARAM_INT]; + try { + $this->conn->insert('group_membership', [ + 'uid' => $uid, + 'gid' => $gid, + ], $types); + } catch (DBALException $exception) { + // do nothing? + } + } +} From 49c6c1d1d5dcc51488c5d08907ffb89ca135486d Mon Sep 17 00:00:00 2001 From: Craig Heydenburg Date: Tue, 24 Mar 2020 14:46:17 -0400 Subject: [PATCH 2/2] ci --- src/Zikula/CoreBundle/Command/GenerateTestUsersCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Zikula/CoreBundle/Command/GenerateTestUsersCommand.php b/src/Zikula/CoreBundle/Command/GenerateTestUsersCommand.php index 88191b3a9c..83e3376b7f 100644 --- a/src/Zikula/CoreBundle/Command/GenerateTestUsersCommand.php +++ b/src/Zikula/CoreBundle/Command/GenerateTestUsersCommand.php @@ -206,7 +206,7 @@ private function createGroup(string $key): int return (int) $this->conn->lastInsertId(); } - private function insertGroup(int $uid, int $gid) : void + private function insertGroup(int $uid, int $gid): void { $types = [\PDO::PARAM_INT, \PDO::PARAM_INT]; try {