diff --git a/README.md b/README.md index 2b36161a..155dc5f1 100644 --- a/README.md +++ b/README.md @@ -6,18 +6,18 @@ Kimai v2 - the reloaded open source Time-Tracking application. ## Introduction -This is the reloaded version of the open source time-tracking application [Kimai](http://www.kimai.org). +This is (or will be in the future, currently a lot of features are still missing) the reloaded version of the open source time-tracking application [Kimai](http://www.kimai.org). -It is based on the following components: - - Symfony Framework 2.x - - AdminLTE Control Panel Template (through the AdminThemeBundle) +It is based on the following PHP components: +- [Symfony Framework 3.4](https://github.com/symfony/symfony) +- [AdminThemeBundle](https://github.com/avanzu/AdminThemeBundle/) (based on [AdminLTE](https://github.com/almasaeed2010/AdminLTE/)) +- [Doctrine](https://github.com/doctrine/) ## Requirements - * PHP 5.5.9 or higher; - * One PHP extension of PDO-SQLite and/or PDO-MySQL enabled; - * and the [usual Symfony application requirements](http://symfony.com/doc/current/reference/requirements.html). - * bower (through npm) +- PHP 7 or higher; +- One PHP extension of PDO-SQLite and/or PDO-MySQL enabled; +- and the [usual Symfony application requirements](http://symfony.com/doc/current/reference/requirements.html) If unsure about meeting these requirements, download the demo application and browse the `http://localhost:8000/config.php` script to get more detailed @@ -25,8 +25,6 @@ information. ## Installation -[![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy) - First, install Git and [Composer](https://getcomposer.org/doc/00-intro.md) if you haven't already. Then, clone this repo and execute this command in the cloned directory: @@ -42,35 +40,60 @@ $ php bin/console assets:install --symlink --relative $ php bin/console avanzu:admin:initialize --symlink --relative ``` - This was the basic task of the installation. If you have not yet setup a database, you can create it and import example data by executing these commands: ```bash $ cd kimai2/ $ php bin/console doctrine:database:create $ php bin/console doctrine:schema:create +``` + +### Creating your first user + +As there is currently no full-fledged installer, you need to create the first user via command-line: + +```bash +$ php bin/console kimai:create-user admin admin@example.com password en ROLE_SUPER_ADMIN +``` + +For available roles, please refer to [the user documentation](app/Resources/docs/users.md). + + +### Demo data + +You can also import demo data, to test the application in its full beauty and with several different user accounts and permission sets. + +```bash $ php bin/console doctrine:fixtures:load ``` -If you have imported the example data, you can login with two accounts: + +If you have imported the example data, you can login with these accounts: - Username: *clara_customer* / Password: *kitten* / Role: Customer - Username: *john_user* / Password: *kitten* / Role: User - Username: *tony_teamlead* / Password: *kitten* / Role: Teamlead - Username: *anna_admin* / Password: *kitten* / Role: Administrator +- Username: *susan_super* / Password: *kitten* / Role: Super-Administrator + +Demo data can always be deleted by dropping the schema and re-creating it (ATTENTION: this will erase all your data!): + +```bash +$ php bin/console doctrine:schema:drop --force +$ php bin/console doctrine:schema:create +``` ## Usage There is no need to configure a virtual host in your web server to access the application. -Just use the built-in web server: +Just use the built-in web server for your first tests: ```bash $ php bin/console server:run ``` This command will start a web server for Kimai. Now you can -access the application in your browser at . You can -stop the built-in web server by pressing `Ctrl + C` while you're in the -terminal. +access the application in your browser at and . +You can stop the built-in web server by pressing `Ctrl + C` while you're in the terminal. > **NOTE** > @@ -84,4 +107,5 @@ terminal. Cannot see any assets (like images) and/or missing styles? Try executing: ```bash $ php bin/console assets:install --symlink -``` \ No newline at end of file +``` + diff --git a/app/Resources/docs/users.md b/app/Resources/docs/users.md new file mode 100644 index 00000000..bc3261a0 --- /dev/null +++ b/app/Resources/docs/users.md @@ -0,0 +1,14 @@ +# Users + +There are multiple pre-defined roles in Kimai, which define the ACLs. A user can only inherit one role, where the roles extend each user. + +## Roles + +| Role name | extends | Gives permission for | +|---|---|---| +| ROLE_CUSTOMER | - | Currently has no permissions, but was reserved for future functionality | +| ROLE_USER | ROLE_CUSTOMER | Time-tracking | +| ROLE_TEAMLEAD | ROLE_USER | All of the above, plus: editing other users timesheets | +| ROLE_ADMIN | ROLE_TEAMLEAD | All of the above, plus: editing customers, editing projects, editing activities | +| ROLE_SUPER_ADMIN | ROLE_ADMIN | All of the above, plus: editing users | + diff --git a/src/AppBundle/Command/CreateUserCommand.php b/src/AppBundle/Command/CreateUserCommand.php new file mode 100644 index 00000000..d64fd9d3 --- /dev/null +++ b/src/AppBundle/Command/CreateUserCommand.php @@ -0,0 +1,128 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace AppBundle\Command; + +use AppBundle\Entity\User; +use Doctrine\Bundle\DoctrineBundle\Registry; +use Symfony\Bridge\Doctrine\RegistryInterface; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\Security\Core\Encoder\UserPasswordEncoder; +use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; +use Symfony\Component\Validator\Validator\ValidatorInterface; + +/** + * Command used to create application user. + * + * @author Kevin Papst + */ +class CreateUserCommand extends Command +{ + /** + * @var UserPasswordEncoder + */ + protected $encoder; + /** + * @var Registry + */ + protected $doctrine; + /** + * @var ValidatorInterface + */ + protected $validator; + + /** + * @param UserPasswordEncoderInterface $encoder + * @param RegistryInterface $registry + * @param ValidatorInterface $validator + */ + public function __construct(UserPasswordEncoderInterface $encoder, RegistryInterface $registry, ValidatorInterface $validator) + { + $this->encoder = $encoder; + $this->doctrine = $registry; + $this->validator = $validator; + + parent::__construct(); + } + + /** + * @inheritdoc + */ + protected function configure() + { + $this + ->setName('kimai:create-user') + ->setDescription('Create a new user') + ->setHelp('This command allows you to create a new user.') + ->addArgument('username', InputArgument::REQUIRED, 'New username (must be unique)') + ->addArgument('email', InputArgument::REQUIRED, 'Users email address (must be unique)') + ->addArgument('password', InputArgument::REQUIRED, 'Users password') + ->addArgument('language', InputArgument::OPTIONAL, 'Users language', User::DEFAULT_LANGUAGE) + ->addArgument('role', InputArgument::OPTIONAL, 'Users role (can be a comma separated list)', User::DEFAULT_ROLE) + ; + } + + /** + * @inheritdoc + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $io = new SymfonyStyle($input, $output); + + $username = $input->getArgument('username'); + $email = $input->getArgument('email'); + $password = $input->getArgument('password'); + $language = $input->getArgument('language'); + $role = $input->getArgument('role'); + + $language = $language ?: User::DEFAULT_LANGUAGE; + $role = $role ?: User::DEFAULT_ROLE; + + $user = new User(); + $user->setUsername($username) + ->setPlainPassword($password) + ->setEmail($email) + ->setLanguage($language) + ->setRoles(explode(',', $role)) + ; + + $pwd = $this->encoder->encodePassword($user, $user->getPlainPassword()); + $user->setPassword($pwd); + + $errors = $this->validator->validate($user); + if ($errors->count() > 0) { + /** @var \Symfony\Component\Validator\ConstraintViolation $error */ + foreach($errors as $error) { + $io->error( + $error->getPropertyPath() + . " (" . (is_array($error->getInvalidValue()) ? implode(',', $error->getInvalidValue()) : $error->getInvalidValue()).")" + . "\n " + . $error->getMessage() + ); + } + return; + } + + try { + $entityManager = $this->doctrine->getManager(); + $entityManager->persist($user); + $entityManager->flush(); + $io->success('Success! Created user: ' . $user->getUsername()); + } catch (\Exception $ex) { + $io->error('Failed to create user: ' . $user->getUsername()); + $io->error('Reason: ' . $ex->getMessage()); + } + } +}