abstract class Check in Security Review 8
Defines a security check.
Hierarchy
- class \Drupal\security_review\Check uses DependencySerializationTrait, StringTranslationTrait
Expanded class hierarchy of Check
16 files declare their use of Check
- AdminPermissions.php in src/
Checks/ AdminPermissions.php - ErrorReporting.php in src/
Checks/ ErrorReporting.php - ExecutablePhp.php in src/
Checks/ ExecutablePhp.php - FailedLogins.php in src/
Checks/ FailedLogins.php - Field.php in src/
Checks/ Field.php
File
- src/
Check.php, line 13
Namespace
Drupal\security_reviewView source
abstract class Check {
use DependencySerializationTrait;
use StringTranslationTrait;
/**
* The configuration storage for this check.
*
* @var \Drupal\Core\Config\Config $config
*/
protected $config;
/**
* The service container.
*
* @var \Symfony\Component\DependencyInjection\ContainerInterface
*/
protected $container;
/**
* Settings handler for this check.
*
* @var \Drupal\security_review\CheckSettingsInterface $settings
*/
protected $settings;
/**
* The State system.
*
* @var \Drupal\Core\State\State
*/
protected $state;
/**
* The check's prefix in the State system.
*
* @var string
*/
protected $statePrefix;
/**
* Initializes the configuration storage and the settings handler.
*/
public function __construct() {
$this->container = \Drupal::getContainer();
$this->config = $this
->configFactory()
->getEditable('security_review.check.' . $this
->id());
$this->settings = new CheckSettings($this, $this->config);
$this->state = $this->container
->get('state');
$this->statePrefix = 'security_review.check.' . $this
->id() . '.';
// Set check ID in config.
if ($this->config
->get('id') != $this
->id()) {
$this->config
->set('id', $this
->id());
$this->config
->save();
}
}
/**
* Returns the namespace of the check.
*
* Usually it's the same as the module's name.
*
* Naming rules (if overridden):
* - All characters should be lowerspace.
* - Use characters only from the english alphabet.
* - Don't use spaces (use "_" instead).
*
* @return string
* Machine namespace of the check.
*/
public function getMachineNamespace() {
$namespace = strtolower($this
->getNamespace());
$namespace = preg_replace("/[^a-z0-9 ]/", '', $namespace);
$namespace = str_replace(' ', '_', $namespace);
return $namespace;
}
/**
* Returns the namespace of the check.
*
* Usually it's the same as the module's name.
*
* @return string
* Human-readable namespace of the check.
*/
public abstract function getNamespace();
/**
* Returns the machine name of the check.
*
* Naming rules (if overridden):
* - All characters should be lowerspace.
* - Use characters only from the english alphabet.
* - Don't use spaces (use "_" instead).
*
* @return string
* ID of check.
*/
public function getMachineTitle() {
$title = strtolower($this
->getTitle());
$title = preg_replace("/[^a-z0-9 ]/", '', $title);
$title = str_replace(' ', '_', $title);
return $title;
}
/**
* Returns the human-readable title of the check.
*
* @return string
* Title of check.
*/
public abstract function getTitle();
/**
* Returns the identifier constructed using the namespace and title values.
*
* @return string
* Unique identifier of the check.
*/
public final function id() {
return $this
->getMachineNamespace() . '-' . $this
->getMachineTitle();
}
/**
* Returns whether the findings should be stored or reproduced when needed.
*
* The only case when this function should return false is if the check can
* generate a lot of findings (like the File permissions check for example).
* Turning this off for checks that don't generate findings at all or just a
* few of them actually means more overhead as the check has to be re-run
* in order to get its last result.
*
* @return bool
* Boolean indicating whether findings will be stored.
*/
public function storesFindings() {
return TRUE;
}
/**
* Returns the check-specific settings' handler.
*
* @return \Drupal\security_review\CheckSettingsInterface
* The settings interface of the check.
*/
public function settings() {
return $this->settings;
}
/**
* The actual procedure of carrying out the check.
*
* @return \Drupal\security_review\CheckResult
* The result of running the check.
*/
public abstract function run();
/**
* Same as run(), but used in CLI context such as Drush.
*
* @return \Drupal\security_review\CheckResult
* The result of running the check.
*/
public function runCli() {
return $this
->run();
}
/**
* Returns the check-specific help page.
*
* @return array
* The render array of the check's help page.
*/
public abstract function help();
/**
* Returns the evaluation page of a result.
*
* Usually this is a list of the findings and an explanation.
*
* @param \Drupal\security_review\CheckResult $result
* The check result to evaluate.
*
* @return array
* The render array of the evaluation page.
*/
public function evaluate(CheckResult $result) {
return [];
}
/**
* Evaluates a CheckResult and returns a plaintext output.
*
* @param \Drupal\security_review\CheckResult $result
* The check result to evaluate.
*
* @return string
* The evaluation string.
*/
public function evaluatePlain(CheckResult $result) {
return '';
}
/**
* Converts a result integer to a human-readable result message.
*
* @param int $result_const
* The result integer.
*
* @return string
* The human-readable result message.
*/
public abstract function getMessage($result_const);
/**
* Returns the last stored result of the check.
*
* Returns null if no results have been stored yet.
*
* @param bool $get_findings
* Whether to get the findings too.
*
* @return \Drupal\security_review\CheckResult|null
* The last stored result (or null).
*/
public function lastResult($get_findings = FALSE) {
// Get stored data from State system.
$state_prefix = $this->statePrefix . 'last_result.';
$result = $this->state
->get($state_prefix . 'result');
if ($get_findings) {
$findings = $this->state
->get($state_prefix . 'findings');
}
else {
$findings = [];
}
$time = $this->state
->get($state_prefix . 'time');
// Force boolean value.
$visible = $this->state
->get($state_prefix . 'visible') == TRUE;
// Check validity of stored data.
$valid_result = is_int($result) && $result >= CheckResult::SUCCESS && $result <= CheckResult::INFO;
$valid_findings = is_array($findings);
$valid_time = is_int($time) && $time > 0;
// If invalid, return NULL.
if (!$valid_result || !$valid_findings || !$valid_time) {
return NULL;
}
// Construct the CheckResult.
$last_result = new CheckResult($this, $result, $findings, $visible, $time);
// Do a check run for acquiring findings if required.
if ($get_findings && !$this
->storesFindings()) {
// Run the check to get the findings.
$fresh_result = $this
->run();
// If it malfunctioned return the last known good result.
if (!$fresh_result instanceof CheckResult) {
return $last_result;
}
if ($fresh_result
->result() != $last_result
->result()) {
// If the result is not the same store the new result and return it.
$this
->storeResult($fresh_result);
$this
->securityReview()
->logCheckResult($fresh_result);
return $fresh_result;
}
else {
// Else return the old result with the fresh one's findings.
return CheckResult::combine($last_result, $fresh_result);
}
}
return $last_result;
}
/**
* Returns the timestamp the check was last run.
*
* Returns 0 if it has not been run yet.
*
* @return int
* The timestamp of the last stored result.
*/
public function lastRun() {
$last_result_time = $this->state
->get($this->statePrefix . 'last_result.time');
if (!is_int($last_result_time)) {
return 0;
}
return $last_result_time;
}
/**
* Returns whether the check is skipped. Checks are not skipped by default.
*
* @return bool
* Boolean indicating whether the check is skipped.
*/
public function isSkipped() {
$is_skipped = $this->config
->get('skipped');
if (!is_bool($is_skipped)) {
return FALSE;
}
return $is_skipped;
}
/**
* Returns the user the check was skipped by.
*
* Returns null if it hasn't been skipped yet or the user that skipped the
* check is not valid anymore.
*
* @return \Drupal\user\Entity\User|null
* The user the check was last skipped by (or null).
*/
public function skippedBy() {
$skipped_by = $this->config
->get('skipped_by');
if (!is_int($skipped_by)) {
return NULL;
}
return User::load($skipped_by);
}
/**
* Returns the timestamp the check was last skipped on.
*
* Returns 0 if it hasn't been skipped yet.
*
* @return int
* The UNIX timestamp the check was last skipped on (or 0).
*/
public function skippedOn() {
$skipped_on = $this->config
->get('skipped_on');
if (!is_int($skipped_on)) {
return 0;
}
return $skipped_on;
}
/**
* Enables the check. Has no effect if the check was not skipped.
*/
public function enable() {
if ($this
->isSkipped()) {
$this->config
->set('skipped', FALSE);
$this->config
->save();
// Log.
$context = [
'@name' => $this
->getTitle(),
];
$this
->securityReview()
->log($this, '@name check no longer skipped', $context, RfcLogLevel::NOTICE);
}
}
/**
* Marks the check as skipped.
*
* It still can be ran manually, but will remain skipped on the Run & Review
* page.
*/
public function skip() {
if (!$this
->isSkipped()) {
// Store skip data.
$this->config
->set('skipped', TRUE);
$this->config
->set('skipped_by', $this
->currentUser()
->id());
$this->config
->set('skipped_on', time());
$this->config
->save();
// Log.
$context = [
'@name' => $this
->getTitle(),
];
$this
->securityReview()
->log($this, '@name check skipped', $context, RfcLogLevel::NOTICE);
}
}
/**
* Stores a result in the state system.
*
* @param \Drupal\security_review\CheckResult $result
* The result to store.
*/
public function storeResult(CheckResult $result) {
if ($result == NULL) {
$context = [
'@reviewcheck' => $this
->getTitle(),
'@namespace' => $this
->getNamespace(),
];
$this
->securityReview()
->log($this, 'Unable to store check @reviewcheck for @namespace', $context, RfcLogLevel::CRITICAL);
return;
}
$findings = $this
->storesFindings() ? $result
->findings() : [];
$this->state
->setMultiple([
$this->statePrefix . 'last_result.result' => $result
->result(),
$this->statePrefix . 'last_result.time' => $result
->time(),
$this->statePrefix . 'last_result.visible' => $result
->isVisible(),
$this->statePrefix . 'last_result.findings' => $findings,
]);
}
/**
* Creates a new CheckResult for this Check.
*
* @param int $result
* The result integer (see the constants defined in CheckResult).
* @param array $findings
* The findings.
* @param bool $visible
* The visibility of the result.
* @param int $time
* The time the test was run.
*
* @return \Drupal\security_review\CheckResult
* The created CheckResult.
*/
public function createResult($result, array $findings = [], $visible = TRUE, $time = NULL) {
return new CheckResult($this, $result, $findings, $visible, $time);
}
/**
* Returns the Security Review Checklist service.
*
* @return \Drupal\security_review\Checklist
* Security Review's Checklist service.
*/
protected function checklist() {
return $this->container
->get('security_review.checklist');
}
/**
* Returns the Config factory.
*
* @return \Drupal\Core\Config\ConfigFactory
* Config factory.
*/
protected function configFactory() {
return $this->container
->get('config.factory');
}
/**
* Returns the service container.
*
* @return \Symfony\Component\DependencyInjection\ContainerInterface
* Service container.
*/
protected function container() {
return $this->container;
}
/**
* Returns the current Drupal user.
*
* @return \Drupal\Core\Session\AccountProxy
* Current Drupal user.
*/
protected function currentUser() {
return $this->container
->get('current_user');
}
/**
* Returns the database connection.
*
* @return \Drupal\Core\Database\Connection
* Database connection.
*/
protected function database() {
return $this->container
->get('database');
}
/**
* Returns the entity type manager.
*
* @return \Drupal\Core\Entity\EntityTypeManagerInterface
* Entity type manager.
*/
protected function entityTypeManager() {
return $this->container
->get('entity_type.manager');
}
/**
* Returns the Drupal Kernel.
*
* @return \Drupal\Core\DrupalKernel
* Drupal Kernel.
*/
protected function kernel() {
return $this->container
->get('kernel');
}
/**
* Returns the module handler.
*
* @return \Drupal\Core\Extension\ModuleHandler
* Module handler.
*/
protected function moduleHandler() {
return $this->container
->get('module_handler');
}
/**
* Returns the Security Review Security service.
*
* @return \Drupal\security_review\Security
* Security Review's Security service.
*/
protected function security() {
return $this->container
->get('security_review.security');
}
/**
* Returns the Security Review service.
*
* @return \Drupal\security_review\SecurityReview
* Security Review service.
*/
protected function securityReview() {
return $this->container
->get('security_review');
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
Check:: |
protected | property | The configuration storage for this check. | |
Check:: |
protected | property | The service container. | |
Check:: |
protected | property | Settings handler for this check. | |
Check:: |
protected | property | The State system. | |
Check:: |
protected | property | The check's prefix in the State system. | |
Check:: |
protected | function | Returns the Security Review Checklist service. | |
Check:: |
protected | function | Returns the Config factory. | |
Check:: |
protected | function | Returns the service container. | |
Check:: |
public | function | Creates a new CheckResult for this Check. | |
Check:: |
protected | function | Returns the current Drupal user. | |
Check:: |
protected | function | Returns the database connection. | |
Check:: |
public | function | Enables the check. Has no effect if the check was not skipped. | |
Check:: |
protected | function | Returns the entity type manager. | |
Check:: |
public | function | Returns the evaluation page of a result. | 13 |
Check:: |
public | function | Evaluates a CheckResult and returns a plaintext output. | 12 |
Check:: |
public | function | Returns the namespace of the check. | |
Check:: |
public | function | Returns the machine name of the check. | 5 |
Check:: |
abstract public | function | Converts a result integer to a human-readable result message. | 14 |
Check:: |
abstract public | function | Returns the namespace of the check. | 14 |
Check:: |
abstract public | function | Returns the human-readable title of the check. | 14 |
Check:: |
abstract public | function | Returns the check-specific help page. | 14 |
Check:: |
final public | function | Returns the identifier constructed using the namespace and title values. | |
Check:: |
public | function | Returns whether the check is skipped. Checks are not skipped by default. | |
Check:: |
protected | function | Returns the Drupal Kernel. | |
Check:: |
public | function | Returns the last stored result of the check. | |
Check:: |
public | function | Returns the timestamp the check was last run. | |
Check:: |
protected | function | Returns the module handler. | |
Check:: |
abstract public | function | The actual procedure of carrying out the check. | 14 |
Check:: |
public | function | Same as run(), but used in CLI context such as Drush. | 2 |
Check:: |
protected | function | Returns the Security Review Security service. | |
Check:: |
protected | function | Returns the Security Review service. | |
Check:: |
public | function | Returns the check-specific settings' handler. | |
Check:: |
public | function | Marks the check as skipped. | |
Check:: |
public | function | Returns the user the check was skipped by. | |
Check:: |
public | function | Returns the timestamp the check was last skipped on. | |
Check:: |
public | function | Stores a result in the state system. | |
Check:: |
public | function | Returns whether the findings should be stored or reproduced when needed. | 2 |
Check:: |
public | function | Initializes the configuration storage and the settings handler. | 2 |
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |