diff --git a/config/packages/kimai.yaml b/config/packages/kimai.yaml index 345b2c00..402e1d48 100644 --- a/config/packages/kimai.yaml +++ b/config/packages/kimai.yaml @@ -1,5 +1,10 @@ kimai: + # Settings for the user management and login forms + user: + registration: true + password_reset: true + # All configs related to timesheet and record management timesheet: diff --git a/config/routes/fos_user.yaml b/config/routes/fos_user.yaml index 40829ab2..439d5e11 100644 --- a/config/routes/fos_user.yaml +++ b/config/routes/fos_user.yaml @@ -3,12 +3,10 @@ fos_user_security: prefix: /{_locale} resource: "@FOSUserBundle/Resources/config/routing/security.xml" -# Expose the user registration feature -fos_user_registration: - prefix: /{_locale}/register - resource: "@FOSUserBundle/Resources/config/routing/registration.xml" - -# Expose the users password-reset feature -fos_user_resetting: - prefix: /{_locale}/resetting - resource: "@FOSUserBundle/Resources/config/routing/resetting.xml" +# The features "user registration" and "password-reset" are enabled by default. +# +# You can disable them by setting the config keys in file "config/kimai.yaml": +# - kimai.user.registration: false +# - kimai.user.password_reset: false +# +# The routes for these functions are added dynamically in src/Kernel.php \ No newline at end of file diff --git a/src/DependencyInjection/AppExtension.php b/src/DependencyInjection/AppExtension.php index 203e827b..7e6fd86a 100644 --- a/src/DependencyInjection/AppExtension.php +++ b/src/DependencyInjection/AppExtension.php @@ -16,12 +16,13 @@ use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; use Symfony\Component\HttpKernel\DependencyInjection\Extension; /** - * This is the class that loads and manages your bundle configuration + * This class that loads and manages the Kimai configuration and container parameter. */ class AppExtension extends Extension implements PrependExtensionInterface { /** - * {@inheritdoc} + * @param array $configs + * @param ContainerBuilder $container */ public function load(array $configs, ContainerBuilder $container) { @@ -36,10 +37,36 @@ class AppExtension extends Extension implements PrependExtensionInterface $container->setParameter('kimai.languages', $config['languages']); $container->setParameter('kimai.calendar', $config['calendar']); + $this->createUserParameter($config, $container); $this->createTimesheetParameter($config, $container); $this->createInvoiceParameter($config, $container); } + /** + * @param array $config + * @param ContainerBuilder $container + */ + public function createUserParameter(array $config, ContainerBuilder $container) + { + if (!$config['user']['registration']) { + $routes = $container->getParameter('admin_lte_theme.routes'); + $routes['adminlte_registration'] = null; + $container->setParameter('admin_lte_theme.routes', $routes); + } + + if (!$config['user']['password_reset']) { + $routes = $container->getParameter('admin_lte_theme.routes'); + $routes['adminlte_password_reset'] = null; + $container->setParameter('admin_lte_theme.routes', $routes); + } + + $container->setParameter('kimai.fosuser', $config['user']); + } + + /** + * @param array $config + * @param ContainerBuilder $container + */ public function createTimesheetParameter(array $config, ContainerBuilder $container) { $container->setParameter('kimai.timesheet.rates', $config['timesheet']['rates']); @@ -91,7 +118,7 @@ class AppExtension extends Extension implements PrependExtensionInterface } /** - * {@inheritdoc} + * @return string */ public function getAlias() { diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 327890fa..f81f4d4d 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -13,7 +13,9 @@ use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; /** - * This is the class that validates and merges configuration from your app/config files + * This class validates and merges configuration from the files: + * - config/packages/kimai.yaml + * - config/packages/local.yaml */ class Configuration implements ConfigurationInterface { @@ -27,6 +29,17 @@ class Configuration implements ConfigurationInterface $rootNode ->children() + ->arrayNode('user') + ->addDefaultsIfNotSet() + ->children() + ->booleanNode('registration') + ->defaultTrue() + ->end() + ->booleanNode('password_reset') + ->defaultTrue() + ->end() + ->end() + ->end() ->arrayNode('timesheet') ->children() ->booleanNode('duration_only') diff --git a/src/Form/Extension/DocumentationLinkExtension.php b/src/Form/Extension/DocumentationLinkExtension.php index 7f225cb1..88c4389d 100644 --- a/src/Form/Extension/DocumentationLinkExtension.php +++ b/src/Form/Extension/DocumentationLinkExtension.php @@ -35,7 +35,7 @@ class DocumentationLinkExtension extends AbstractTypeExtension */ public function buildView(FormView $view, FormInterface $form, array $options) { - $view->vars['documentation'] = $options['documentation'] ?? ''; + $view->vars['docu_chapter'] = $options['docu_chapter'] ?? null; } /** @@ -43,7 +43,8 @@ class DocumentationLinkExtension extends AbstractTypeExtension */ public function configureOptions(OptionsResolver $resolver) { - $resolver->setDefined(['documentation']); - $resolver->setDefaults(['documentation' => null]); + $resolver->setDefined(['docu_chapter']); + $resolver->setAllowedTypes('docu_chapter', 'string'); + $resolver->setDefault('docu_chapter', ''); } } diff --git a/src/Form/TimesheetEditForm.php b/src/Form/TimesheetEditForm.php index 052829f0..99fe4e12 100644 --- a/src/Form/TimesheetEditForm.php +++ b/src/Form/TimesheetEditForm.php @@ -93,7 +93,7 @@ class TimesheetEditForm extends AbstractType 'csrf_token_id' => 'timesheet_edit', 'duration_only' => false, 'include_user' => false, - 'documentation' => 'timesheet', + 'docu_chapter' => 'timesheet', ]); } } diff --git a/src/Kernel.php b/src/Kernel.php index 11022a87..2892a2ed 100644 --- a/src/Kernel.php +++ b/src/Kernel.php @@ -71,12 +71,42 @@ class Kernel extends BaseKernel protected function configureRoutes(RouteCollectionBuilder $routes) { $confDir = $this->getProjectDir() . '/config'; + + // some routes are based on app configs and will be imported manually + $this->configureFosUserRoutes($routes); + + // load bundle specific route files if (is_dir($confDir . '/routes/')) { $routes->import($confDir . '/routes/*' . self::CONFIG_EXTS, '/', 'glob'); } + + // load environment specific route files if (is_dir($confDir . '/routes/' . $this->environment)) { $routes->import($confDir . '/routes/' . $this->environment . '/**/*' . self::CONFIG_EXTS, '/', 'glob'); } + + // load application routes $routes->import($confDir . '/routes' . self::CONFIG_EXTS, '/', 'glob'); } + + protected function configureFosUserRoutes(RouteCollectionBuilder $routes) + { + $features = $this->getContainer()->getParameter('kimai.fosuser'); + + // Expose the user registration feature + if ($features['registration']) { + $routes->import( + '@FOSUserBundle/Resources/config/routing/registration.xml', + '/{_locale}/register' + ); + } + + // Expose the users password-reset feature + if ($features['password_reset']) { + $routes->import( + '@FOSUserBundle/Resources/config/routing/resetting.xml', + '/{_locale}/resetting' + ); + } + } } diff --git a/templates/default/_form.html.twig b/templates/default/_form.html.twig index 583e37bb..27cc6d64 100644 --- a/templates/default/_form.html.twig +++ b/templates/default/_form.html.twig @@ -2,8 +2,8 @@
diff --git a/templates/form/kimai-theme.html.twig b/templates/form/kimai-theme.html.twig index 88b1bcdc..c245c59d 100644 --- a/templates/form/kimai-theme.html.twig +++ b/templates/form/kimai-theme.html.twig @@ -1,8 +1,8 @@ {% extends "@AdminLTE/layout/form-theme.html.twig" %} {% block form_label %} - {% if form.vars.documentation is defined and form.vars.documentation is not empty %} - + {% if form.vars.docu_chapter is defined and form.vars.docu_chapter is not empty %} + {% endif %} {{ parent() }} {% endblock form_label %} diff --git a/tests/Controller/TimesheetControllerTest.php b/tests/Controller/TimesheetControllerTest.php index a96830fe..dc50d9ff 100644 --- a/tests/Controller/TimesheetControllerTest.php +++ b/tests/Controller/TimesheetControllerTest.php @@ -9,6 +9,9 @@ namespace App\Tests\Controller; +use App\Entity\User; +use App\Tests\DataFixtures\TimesheetFixtures; + /** * @coversDefaultClass \App\Controller\TimesheetController * @group integration @@ -28,4 +31,47 @@ class TimesheetControllerTest extends ControllerBaseTest $this->assertTrue($client->getResponse()->isSuccessful()); $this->assertHasDataTable($client); } + + public function testCreateAction() + { + $client = $this->getClientForAuthenticatedUser(); + $this->request($client, '/timesheet/create'); + $this->assertTrue($client->getResponse()->isSuccessful()); + // TODO more tests + } + + public function testCreateActionWithFromAndToValues() + { + $client = $this->getClientForAuthenticatedUser(); + $this->request($client, '/timesheet/create?from=2018-08-02T20%3A00%3A00&to=2018-08-02T20%3A30%3A00'); + $this->assertTrue($client->getResponse()->isSuccessful()); + // TODO more tests + } + + public function testEditAction() + { + $client = $this->getClientForAuthenticatedUser(); + + $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $fixture = new TimesheetFixtures(); + $fixture->setAmount(10); + $fixture->setUser($this->getUserByRole($em, User::ROLE_USER)); + $fixture->setStartDate('2017-05-01'); + $this->importFixture($em, $fixture); + + $this->request($client, '/timesheet/1/edit'); + + $response = $client->getResponse(); + + $docuUrl = $this->createUrl('/help/timesheet'); + $this->assertTrue($response->isSuccessful()); + $this->assertContains( + '', + $response->getContent(), + 'Could not find link to documentation' + ); + + // TODO more tests + } + } diff --git a/var/docs/configurations.md b/var/docs/configurations.md index 5c9dd7bd..94d4d043 100644 --- a/var/docs/configurations.md +++ b/var/docs/configurations.md @@ -1,17 +1,5 @@ # Configurations -Configuration of Kimai is spread in all files in the `config/`directory but mainly it these files: - -- `.env` - environment specific settings -- `config/packages/kimai.yaml` - Kimai specific settings -- `config/packages/admin_lte.yaml` - theme specific settings ([read more](https://github.com/kevinpapst/AdminLTEBundle/blob/master/Resources/docs/configurations.md)) -- `config/packages/fos_user.yaml` - user management and email settings -- `config/packages/local.yaml` - your local configuration settings - -There are several other configurations that could potentially be interesting for you in [config/packages/*.yaml](../../config/packages/). - -If you want to adjust a setting from any of these files, use `local.yaml` (see below). - ## Environment specific settings (.env) The most basic settings, which need always be adjusted are stored in the `.env` file: @@ -23,6 +11,20 @@ The most basic settings, which need always be adjusted are stored in the `.env` - `DATABASE_PREFIX` - precix for any Kimai table in the configured database - `APP_SECRET` - secret used for hasing user password (if you cahnge this, every password is invalid afterwards) +## Config files + +Configuration of Kimai is spread in all files in the `config/`directory but mainly it these files: + +- `.env` - environment specific settings +- `config/packages/kimai.yaml` - Kimai specific settings +- `config/packages/admin_lte.yaml` - theme specific settings ([read more](https://github.com/kevinpapst/AdminLTEBundle/blob/master/Resources/docs/configurations.md)) +- `config/packages/fos_user.yaml` - user management and email settings +- `config/packages/local.yaml` - your local configuration settings + +There are several other configurations that could potentially be interesting for you in [config/packages/*.yaml](../../config/packages/). + +If you want to adjust a setting from any of these files, use `local.yaml`. + ## Overwriting local configs (local.yaml) You can create the file `config/packages/local.yaml` and store your own settings inside. This file will NEVER be shipped with Kimai. @@ -45,14 +47,25 @@ admin_lte: The `local.yaml` file will be imported as last configuration file, so you can overwrite any setting from the `config/packages/` directory. -After changing this file you have to clear the cache with `bin/console cache:clear` or `bin/console cache:clear --env=prod`. +Whenever the documentation asks you to edit a yaml file from the `config/packages/` directory, it means you should copy +this specific configuration key to your `local.yaml` in order to overwrite the default configuration. + +## Reload changed configurations + +When you change a configuration file, Kimai will not see this change immediately. +You can reload the configs after you are done by rebuilding the Symfony cache with: + +```bash +bin/console cache:clear --env=prod +bin/console cache:warmup --env=prod +``` + +Depending on your setup it might be necessary to execute these commands as webserver user, +please read the [UPGRADING guide](../../UPGRADING.md) for more details. ## Emails (swiftmailer.yaml) -Kimai uses Swiftmailer to sent emails. You configure your SMTP connection setting in [.env](../../.env.sample). - -For more configuration details read the [Swiftmailer](https://symfony.com/doc/current/reference/configuration/swiftmailer.html) documentation -and apply the settings in [swiftmailer.yaml](../../config/packages/swiftmailer.yaml). +Read more about [email configuration](emails.md). ## Security @@ -60,15 +73,62 @@ Kimai uses the FOSUserBundle for security related tasks like user management. It ### User management emails (fos_user.yaml) -Kimai sents emails for newly registered users ([if that is configured](users.md)) and forgotten password requests. -You can change the contents of these emails by editing [fos_user.yaml](../../config/packages/fos_user.yaml). - -You can find more information in the [FOSUserBundle](https://symfony.com/doc/master/bundles/FOSUserBundle/index.html) documentation. +Read more about [email configuration](emails.md). ### Remember me login (security.yaml) The default period for the `Remember me` option can be changed in the config file [security.yaml](../../config/packages/security.yaml). +### User registration + +If you want your new users to use [email](emails.md) based activation add this to your `local.yaml`: + +```yaml +fos_user: + registration: + confirmation: + enabled: true +``` + +#### Disable user registration + +If you want to disable the user registration, add this your `local.yaml`: +```yaml +kimai: + user: + registration: false +``` + +If you only want to hide the link from the login form but keep the functionality, add this your `local.yaml`: +```yaml +admin_lte: + routes: + adminlte_registration: ~ +``` + +### Password reset + +If you want to configure the behaviour (like the allowed time between multiple retries) then configure the settings: + +- in `config/packages/fos_user.yaml` the key below `fos_user.registration.resetting` (see [documentation](https://symfony.com/doc/current/bundles/FOSUserBundle/configuration_reference.html)) +- the values `retry_ttl` and `token_ttl` are configured in seconds (7220 = 2 hours) + +#### Disable password reset + +If you want to disable the password reset, add this your `local.yaml`: +```yaml +kimai: + user: + password_reset: false +``` + +If you only want to hide the link from the login form but keep the functionality, add this your `local.yaml`: +```yaml +admin_lte: + routes: + adminlte_password_reset: ~ +``` + ## Timesheets (kimai.yaml) ### Duration only diff --git a/var/docs/emails.md b/var/docs/emails.md index bc5a52b8..f5604263 100644 --- a/var/docs/emails.md +++ b/var/docs/emails.md @@ -1,9 +1,9 @@ # Emails Kimai uses the [Swift MailerBundle](https://symfony.com/doc/current/email.html) for sending emails. -Please read their documentation, there are a lot of possible configuration settings that you might want to adapt to your needs. +Please read their documentation, there are a lot of possible [configuration settings](https://symfony.com/doc/current/reference/configuration/swiftmailer.html) that you might want to adapt to your needs. -If not otherwise noted, all emails will be sent instantly (unless spooling is activated in `config/packages/swiftmailer.yaml`). +If not otherwise noted, all emails will be sent instantly (unless spooling is activated in [swiftmailer.yaml](../../config/packages/swiftmailer.yaml)). ## Activating email diff --git a/var/docs/users.md b/var/docs/users.md index c0e2a058..e7719894 100644 --- a/var/docs/users.md +++ b/var/docs/users.md @@ -35,18 +35,13 @@ Read the [configurations chapter](configurations.md) if you want to change the v ## User registration User registration with instant approval is activated by default, so users can register and will be able to login and start time-tracking instantly. -If you want your new users to use [email](emails.md) based activation, you need to change the following configuration: -- in `config/packages/fos_user.yaml` change the setting `fos_user.registration.confirmation.enabled` to true (default: false) - -If you want to deactivate the user registration completely, you have to change the following configs: - -- in `config/packages/admin_lte.yaml` remove the route alias `admin_lte.routes.adminlte_registration` (this will remove the link from the login form) -- in `config/routes.yaml` remove the block `fos_user_registration` (this will deactivate the functionality) +Read the [configurations chapter](configurations.md) if you want to disable the registration or enable email verification. ## Password reset -The reset password function is enabled by default, read how to activate [email](emails.md) support. +The reset password function is enabled by default, but you need to activate [email](emails.md) support if you want to use it. + If you want to deactivate this feature you have to change the following configs: - in `config/packages/admin_lte.yaml` remove the route alias `admin_lte.routes.adminlte_password_reset` (this will remove the link from the login form) @@ -55,4 +50,6 @@ If you want to deactivate this feature you have to change the following configs: If you want to configure the behaviour (like the allowed time between multiple retries) then configure the settings: - in `config/packages/fos_user.yaml` the key below `fos_user.registration.resetting` (see [documentation](https://symfony.com/doc/current/bundles/FOSUserBundle/configuration_reference.html)) -- the values `retry_ttl` and `token_ttl` are configured in seconds (7220 = 2 hours) \ No newline at end of file +- the values `retry_ttl` and `token_ttl` are configured in seconds (7220 = 2 hours) + +Read the [configurations chapter](configurations.md) if you want to reload the changed configuration files.