Problem/Motivation

If I am not using a test account It should be deactivated after a configurable amount of time.

Steps to reproduce

N/A

Proposed resolution

If the user account is open after a configurable amount of time this should be disabled after a cron run.

Remaining tasks

N/A

User interface changes

add new setting for the amount of time after which the account will be disabled.

API changes

N/A

Data model changes

N/A

Comments

Guillaume.Klomp created an issue. See original summary.

Guillaume.Klomp’s picture

Status: Active » Needs review
StatusFileSize
new6.36 KB

Here is the fix.

idebr’s picture

Title: automaticly disable Test account » Automatically block test accounts after a configurable period of inactivity
Version: 8.x-1.2 » 8.x-1.x-dev
Status: Needs review » Needs work
  1. +++ b/config/schema/role_test_accounts.schema.yml
    @@ -11,3 +11,6 @@ role_test_accounts.settings:
    +      label: Disable after
    

    The Drupal uses 'Active' and 'Blocked' for the user status. I suggest we use the interface text 'Block account after period of inactivity'

  2. +++ b/role_test_accounts.info.yml
    @@ -8,3 +8,8 @@ dependencies:
    +
    +# Information added by Drupal.org packaging script on 2020-06-18
    +version: '8.x-1.2'
    +project: 'role_test_accounts'
    +datestamp: 1592491181
    

    The patch was created from a release, so it includes package information. Instructions on how to create a patch without this information are available at https://www.drupal.org/node/707484

  3. +++ b/role_test_accounts.install
    @@ -41,3 +41,11 @@ function role_test_accounts_update_8102() {
    + * Implements hook_ENTITY_TYPE_insert().
    

    This hook description does not match the code.

  4. +++ b/role_test_accounts.install
    @@ -41,3 +41,11 @@ function role_test_accounts_update_8102() {
    +function role_test_accounts_update_8103() {
    +  $config = \Drupal::configFactory()->getEditable('role_test_accounts.settings');
    +  $config->set('disable_after', 7200)->save(TRUE);
    +}
    

    This new option can be in the optional schema for new installations, but should be 0 for existing installations so the module keeps working as before.

  5. +++ b/role_test_accounts.module
    @@ -23,3 +23,22 @@ function role_test_accounts_user_role_insert(EntityInterface $entity) {
    +    ->condition('access', \Drupal::time()->getRequestTime() - $config->get('disable_after'), '<')
    +    ->condition('access', 0, '>=');
    

    This condition can use 'BETWEEN' for better readability, see https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21...

  6. +++ b/role_test_accounts.module
    @@ -23,3 +23,22 @@ function role_test_accounts_user_role_insert(EntityInterface $entity) {
    +  \Drupal::queue('disable_test_account_queue')->createItem(['uids' => $uids]);
    

    Given the limited amount of test accounts, there is no need for a queue worker.

  7. +++ b/src/Form/RoleTestAccountsSettingsForm.php
    @@ -67,7 +67,43 @@ class RoleTestAccountsSettingsForm extends ConfigFormBase {
    +    $form['disable']['disable_after'] = [
    +      '#type' => 'textfield',
    +      '#title' => $this->t('disable after'),
    +      '#description' => $this->t('Set the amount of time the test account will be open for.'),
    +      '#default_value' => $config->get('disable_after') > 0 ? $config->get('disable_after') : 7200,
    +      '#states' => [
    +        'visible' => [
    +          ':input[name="automatically_disable"]' => ['checked' => TRUE],
    +        ],
    +        'required' => [
    +          ':input[name="automatically_disable"]' => ['checked' => TRUE],
    +        ],
    +      ],
    +    ];
    

    Since this a module for developers, let's just use the time field and skip the checkbox.

  8. +++ b/src/Form/RoleTestAccountsSettingsForm.php
    @@ -67,7 +67,43 @@ class RoleTestAccountsSettingsForm extends ConfigFormBase {
    +    if ($form_state->isValueEmpty('disable_after') || strval($form_state->getValue('disable_after')) !== strval(intval($form_state->getValue('disable_after')))) {
    +      $form_state->setErrorByName('disable_after', $this->t('Only time in seconds is allowed.'));
    +    }
    

    A form field of 'type' => 'number' will only allow entering of integers. Config validation can do the server-side validation.

  9. +++ b/src/Form/RoleTestAccountsSettingsForm.php
    @@ -81,6 +117,12 @@ class RoleTestAccountsSettingsForm extends ConfigFormBase {
    +      $config->set('disable_after', (int) $form_state->getValue('disable_after'));
    

    No need to type hint to integer here, since the configuration property has a config schema.

Guillaume.Klomp’s picture

StatusFileSize
new4.96 KB
new5.73 KB

Rework for my last patch

Guillaume.Klomp’s picture

Status: Needs work » Needs review
idebr’s picture

Status: Needs review » Needs work
  1. +++ b/config/schema/role_test_accounts.schema.yml
    @@ -11,3 +11,6 @@ role_test_accounts.settings:
    +    disable_after:
    

    disable_after -> block_after

  2. +++ b/config/schema/role_test_accounts.schema.yml
    @@ -11,3 +11,6 @@ role_test_accounts.settings:
    +      label: Block account after period of inactivity
    

    Let's match this text with the form label on the configuration form for consistency.

  3. +++ b/role_test_accounts.install
    @@ -41,3 +41,13 @@ function role_test_accounts_update_8102() {
    + * Implements hook_update_N().
    

    This text is displayed in the console when processing database updates, so it should describe the update being performanced. In this case 'Set a default value for <form label>'

  4. +++ b/role_test_accounts.module
    @@ -23,3 +24,28 @@ function role_test_accounts_user_role_insert(EntityInterface $entity) {
    +/**
    + * Implements hook_cron().
    + */
    +function role_test_accounts_cron() {
    

    This code can be a new service RoleTestAccountBlocker, and should be called after changing the configuration period.

  5. +++ b/role_test_accounts.module
    @@ -23,3 +24,28 @@ function role_test_accounts_user_role_insert(EntityInterface $entity) {
    +  // Disable test.* users that are inactive for more than 2 hours.
    +  $query = \Drupal::entityQuery('user')
    +    ->condition('name', 'test.%', 'LIKE')
    +    ->condition('status', 1, '=')
    +    ->condition('access', $access, 'BETWEEN');
    +  $uids = $query->execute();
    

    There is no need to query inactive users when the timer is 0

  6. +++ b/src/Form/RoleTestAccountsSettingsForm.php
    @@ -67,7 +67,30 @@ class RoleTestAccountsSettingsForm extends ConfigFormBase {
    +      '#title' => $this->t('Disable test accounts'),
    

    Disable -> Block

  7. +++ b/src/Form/RoleTestAccountsSettingsForm.php
    @@ -67,7 +67,30 @@ class RoleTestAccountsSettingsForm extends ConfigFormBase {
    +      '#description' => $this->t('Set a timer to automaticly block a test account.'),
    

    automaticly -> automatically

  8. +++ b/src/Form/RoleTestAccountsSettingsForm.php
    @@ -67,7 +67,30 @@ class RoleTestAccountsSettingsForm extends ConfigFormBase {
    +      '#title' => $this->t('disable after'),
    +      '#description' => $this->t('Set the amount of time the test account will be open for.'),
    

    There is no indication of how 'time' should be entered. Perhaps add a suffix 'seconds' here, so the unit is clear.

  9. +++ b/src/Form/RoleTestAccountsSettingsForm.php
    @@ -67,7 +67,30 @@ class RoleTestAccountsSettingsForm extends ConfigFormBase {
    +    //check if time is in seconds and filled in
    +    if (empty($form_state->getValue('disable_after')) && $form_state->getValue('disable_after') !== '0' || strval($form_state->getValue('disable_after')) !== strval(intval($form_state->getValue('disable_after')))) {
    +      $form_state->setErrorByName('disable_after', $this->t('Only time in seconds is allowed.'));
    +    }
    

    You can configure the minimum value for a "number" field in its renderable array:
    '#type' => 'number',
    '#min' => 0

Guillaume.Klomp’s picture

Status: Needs work » Needs review
StatusFileSize
new8.87 KB
new2.46 KB

Here is the new patch

idebr’s picture

StatusFileSize
new11.41 KB
new7.84 KB

Attached patch implements the following changes:

  1. Blocked accounts are now reactivated when the 'Block after' is set to 0, or the user's last access was in the recent past.
  2. The account status is now determined by the existing RoleTestAccountsManager
  3. The RoleTestAccountsManager is now called when the configuration changes rather than on form save, so the new status is set correctly when deploying configuration.

  • Guillaume.Klomp authored 2299fe0 on 8.x-1.x
    Issue #3162401 by Guillaume.Klomp, idebr: Automatically block test...
idebr’s picture

Status: Needs review » Fixed

Committed, thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.