You are here

public function UserIntegritySensorPlugin::runSensor in Monitoring 8

Runs the sensor, updating $sensor_result.

An implementation must provide any checks necessary to be able to populate the provides sensor result instance with a combination of the following possibilities:

  • Set the sensor status to critical, warning, ok, info or unknown with SensorResultInterface::setStatus(). Defaults to unknown.
  • Set the sensor value with SensorResultInterface::setValue(). This can be a number or a string. Note that value_type defaults to numeric. If a sensor does not return a numeric result, it must be defined accordingly.
  • Set the expected sensor value with SensorResultInterface::setExpectedValue(). When doing so, it is not necessary to set the sensor status explicitly, as that will happen implicitly. See below.
  • Set the sensor message with SensorResultInterface::setMessage(), which will then be used as is. The message must include all relevant information.
  • Add any number of status messages which will then be added to the final sensor message.

Based on the provided information, the sensor result will then be compiled. It will attempt to set the sensor status if not already done explicitly by the sensor and will build a default message, unless a message was already set with SensorResultInterface::setMessage().

Sensors with unknown status can either be set based on an expected value or thresholds. If the value does not match the expected value, the status is set to critical. All numeric sensors have support for thresholds.

The default sensor message will include information about the sensor value, expected value, thresholds, the configured time interval and additional status messages defined. Provided value labels and value types will be considered for displaying the sensor value. If neither value nor status messages are provided, the message will default to "No value".

Compiled message examples:

  • $90.00 in 1 day, expected $100.00. This is the message for a sensor with a commerce_currency value type, a configured time interval of one day and a value of 90 and expected value of 100.
  • 53 login attempts in 6 hours, exceeds 20, 10 for user administrator. This the message for a failed login sensor with value 53 with a threshold configuration of exceeds 20 and a status message "10 for user administrator".

Parameters

\Drupal\monitoring\Result\SensorResultInterface $sensor_result: Sensor result object.

Throws

\Exception Can throw any exception. Must be caught and handled by the caller.

Overrides SensorPluginInterface::runSensor

See also

\Drupal\monitoring\Result\SensorResultInterface::setValue()

\Drupal\monitoring\Result\SensorResultInterface::setExpectedValue()

\Drupal\monitoring\Result\SensorResultInterface::compile()

\Drupal\monitoring\Result\SensorResultInterface::setMessage()

\Drupal\monitoring\Result\SensorResultInterface::addStatusMessage()

File

src/Plugin/monitoring/SensorPlugin/UserIntegritySensorPlugin.php, line 54
Contains \Drupal\monitoring\Plugin\monitoring\SensorPlugin\UserIntegritySensorPlugin.

Class

UserIntegritySensorPlugin
Monitors user data changes.

Namespace

Drupal\monitoring\Plugin\monitoring\SensorPlugin

Code

public function runSensor(SensorResultInterface $sensor_result) {

  // Get role IDs with restricted permissions.
  $role_ids = $this
    ->getRestrictedRoles();
  $current_users = $this
    ->processUsers($this
    ->loadCurrentUsers($role_ids));

  // Add sensor message, count of current privileged users.
  $sensor_result
    ->addStatusMessage(count($current_users) . ' privileged user(s)');
  $sensor_result
    ->setStatus(SensorResultInterface::STATUS_OK);

  // Load old user data.
  $old_users = \Drupal::keyValue('monitoring.users')
    ->getAll();

  // If user data is not stored, store them first.
  if (empty($old_users)) {
    foreach ($current_users as $user) {
      \Drupal::keyValue('monitoring.users')
        ->set($user['id'], $user);
    }
  }
  else {
    $new_users = array_diff_key($current_users, $old_users);
    if (!empty($new_users)) {
      $sensor_result
        ->setStatus(SensorResultInterface::STATUS_WARNING);
      $sensor_result
        ->addStatusMessage(count($new_users) . ' new user(s)');
    }

    // Get the count of privileged users with changes.
    $count = 0;
    $changed_users_ids = array_intersect(array_keys($current_users), array_keys($old_users));
    foreach ($changed_users_ids as $changed_user_id) {
      $changed = $this
        ->getUserChanges($current_users[$changed_user_id], $old_users[$changed_user_id]);
      if (!empty($changed)) {
        $count++;
      }
    }
    if ($count > 0) {
      $sensor_result
        ->addStatusMessage($count . ' changed user(s)');
      $sensor_result
        ->setStatus(SensorResultInterface::STATUS_WARNING);
    }
  }

  // Check anonymous and authenticated users with restricted permissions and
  // show a message.
  $user_register = \Drupal::config('user.settings')
    ->get('register');

  // Check if authenticated or anonymous users have restrict access perms.
  $role_ids_after = array_intersect($role_ids, [
    'authenticated',
    'anonymous',
  ]);
  $role_labels = [];
  foreach (Role::loadMultiple($role_ids_after) as $role) {
    $role_labels[$role
      ->id()] = $role
      ->label();
  }
  if (!empty($role_labels)) {
    $sensor_result
      ->addStatusMessage('Privileged access for roles @roles', array(
      '@roles' => implode(', ', $role_labels),
    ));
    $sensor_result
      ->setStatus(SensorResultInterface::STATUS_WARNING);
  }

  // Further escalate if the restricted access is for anonymous.
  if (in_array('anonymous', $role_ids)) {
    $sensor_result
      ->setStatus(SensorResultInterface::STATUS_CRITICAL);
  }

  // Check if self registration is possible.
  if (in_array('authenticated', $role_ids) && $user_register != UserInterface::REGISTER_ADMINISTRATORS_ONLY) {
    $sensor_result
      ->addStatusMessage('Self registration possible.');
    $sensor_result
      ->setStatus(SensorResultInterface::STATUS_CRITICAL);
  }
}