Plugin Drupal8
ConfigAnalysis
Check a configuration is set correctly.
Class: Drutiny\Plugin\Drupal8\Audit\ConfigAnalysis
Extends: Drutiny\Audit\AbstractAnalysis
Package: drutiny/plugin-drupal-8
Parameters
Name | Type | Description | Default |
---|---|---|---|
collection | string | The collection the config belongs to. | null |
expression | string | The expression language expression to evaluate. | null |
Tokens
Name | Type | Description | Default |
---|---|---|---|
collection | string | The collection the config belongs to. | null |
expression | string | The expression language expression to evaluate. | null |
config | mixed | The returned collection config. | null |
Source
public function gather(Sandbox $sandbox) {
$collection = $sandbox->getParameter('collection');
$config = $sandbox->drush([
'format' => 'json',
'include-overridden' => NULL,
])->configGet($collection);
$sandbox->setParameter('config', $config);
}
final public function audit(Sandbox $sandbox)
{
$this->gather($sandbox);
$expressionLanguage = new ExpressionLanguage($sandbox);
$variables = $sandbox->getParameterTokens();
$sandbox->logger()->debug(__CLASS__ . ': ' . Yaml::dump($variables));
$expression = $sandbox->getParameter('not_applicable', 'false');
$sandbox->logger()->debug(__CLASS__ . ': ' . $expression);
if (@$expressionLanguage->evaluate($expression, $variables)) {
return self::NOT_APPLICABLE;
}
$expression = $sandbox->getParameter('expression', 'true');
$sandbox->logger()->info(__CLASS__ . ': ' . $expression);
return @$expressionLanguage->evaluate($expression, $variables);
}
ConfigCheck
Check a configuration is set correctly.
Class: Drutiny\Plugin\Drupal8\Audit\ConfigCheck
Extends: Drutiny\Audit\AbstractComparison
Package: drutiny/plugin-drupal-8
This class can remediate failed audits.
Policies
These are the policies that use this class:
Name | Title |
---|---|
Drupal-8:JsAggregation | Javascript aggregation |
Drupal-8:PageCacheExpiry | Drupal Page cache expiry is set |
Drupal-8:ErrorLevel | Hide errors from screen (log only) |
Drupal-8:honeypotTimeLimit | Honeypot Time Limit |
Drupal-8:CssAggregation | CSS aggregation is enabled |
Drupal-8:UserRegistrationAdminOnly | User registration available to administrators only |
Drupal-8:Fast404Enabled | Core Fast 404 Enabled |
Parameters
Name | Type | Description | Default |
---|---|---|---|
collection | string | The collection the config belongs to. | null |
key | string | The key the config belongs to. | null |
value | mixed | The value to compare against the retrived value. | null |
comp_type | string | The type of comparison to conduct. Defaults to equals. See Drutiny\Audit\AbstractComparison | null |
Tokens
Name | Type | Description | Default |
---|---|---|---|
collection | string | The collection the config belongs to. | null |
key | string | The key the config belongs to. | null |
value | mixed | The value to compare against the retrived value. | null |
comp_type | string | The type of comparison to conduct. Defaults to equals. See Drutiny\Audit\AbstractComparison | null |
Source
public function audit(Sandbox $sandbox) {
$collection = $sandbox->getParameter('collection');
$key = $sandbox->getParameter('key');
$value = $sandbox->getParameter('value');
$config = $sandbox->drush([
'format' => 'json',
'include-overridden' => NULL,
])->configGet($collection, $key);
$reading = $config[$collection . ':' . $key];
$sandbox->setParameter('reading', $reading);
return $this->compare($reading, $value, $sandbox);
}
CronHasRun
Cron last run.
Class: Drutiny\Plugin\Drupal8\Audit\CronHasRun
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-8
Policies
These are the policies that use this class:
Name | Title |
---|---|
Drupal-8:CronHasRun | Cron last run |
Parameters
Name | Type | Description | Default |
---|---|---|---|
cron_max_interval | integer | The maximum interval between | null |
Tokens
Name | Type | Description | Default |
---|---|---|---|
cron_max_interval | integer | The maximum interval between | null |
Source
public function audit(Sandbox $sandbox) {
try {
$timestamp = $sandbox->drush(['format' => 'json'])->stateGet('system.cron_last');
}
catch (DrushFormatException $e) {
return FALSE;
}
// Check that cron was run in the last day.
$since = time() - $timestamp;
$sandbox->setParameter('cron_last', date('Y-m-d H:i:s', $timestamp));
if ($since > $sandbox->getParameter('cron_max_interval')) {
return FALSE;
}
return TRUE;
}
CronLast
Check a configuration is set correctly.
Class: Drutiny\Plugin\Drupal8\Audit\CronLast
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-8
Policies
These are the policies that use this class:
Name | Title |
---|---|
Drupal-8:CronLast | Cron running regularly |
Source
public function audit(Sandbox $sandbox) {
try {
$last = $sandbox->drush([
'format' => 'json'
])->stateGet('system.cron_last');
if (empty($last)) {
return FALSE;
}
$sandbox->setParameter('cron_last', date('l jS \of F Y h:i:s A', $last));
$time_diff = time() - $last;
// Fail if cron hasn't run in the last 24 hours.
if ($time_diff > 86400) {
return FALSE;
}
return TRUE;
}
catch (DrushFormatException $e) {
return Audit::ERROR;
}
}
DuplicateModules
Duplicate modules.
Class: Drutiny\Plugin\Drupal8\Audit\DuplicateModules
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-8
Policies
These are the policies that use this class:
Name | Title |
---|---|
Drupal-8:DuplicateModules | No duplicate modules found |
Source
public function audit(Sandbox $sandbox) {
$config = $sandbox->drush(['format' => 'json'])
->status();
$docroot = $config['root'];
$command = <<<CMD
find $docroot -name '*.info.yml' -type f |\
grep -Ev '/themes/|/test' |\
grep -oe '[^/]*\.info.yml' | cut -d'.' -f1 | sort |\
uniq -c | sort -nr | awk '{print $2": "$1}'
CMD;
$output = $sandbox->exec($command);
if (empty($output)) {
return TRUE;
}
// Ignore modules where there are only 1 of them.
$module_count = array_filter(Yaml::parse($output), function ($count) {
return $count > 1;
});
$sandbox->setParameter('duplicate_modules', array_keys($module_count));
return count($module_count) == 0;
}
ModuleDisabled
Generic module is disabled check.
Class: Drutiny\Plugin\Drupal8\Audit\ModuleDisabled
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-8
This class can remediate failed audits.
Policies
These are the policies that use this class:
Name | Title |
---|---|
Drupal-8:acquiaCASDisabled | CAS is not installed |
Drupal-8:acquiaDevinciDisabled | Devinci is not installed |
Drupal-8:acquiaR4032LoginDisabled | Redirect 403 to User Login is not installed |
Drupal-8:acquiaHTMLPurifierDisabled | HTML Purifier is not installed |
Drupal-8:acquiaDropzoneJSDisabled | Dropzone JS is not installed |
Drupal-8:acquiaTCPDFDisabled | TCPDF is not installed |
Drupal-8:acquiaConfigMgmtDisabled | Configuration Management is not installed |
Drupal-8:acquiaCFPurgeDisabled | CloudFlare Purge is not installed |
Drupal-8:acquiaRadioactivityDisabled | Radioactivity is not installed |
Drupal-8:acquiaOptimizeDBDisabled | Optimize DB is not installed |
Drupal-8:acquiaShibAuthDisabled | Shibboleth Authentication is not installed |
Drupal-8:acquiaWURFLDisabled | WURFL is not installed |
Drupal-8:acquiaSerialDisabled | Serial is not installed |
Drupal-8:acquiaVarnishModuleDisabled | Varnish Module is not installed |
Drupal-8:acquiaBoostDisabled | Boost is not installed |
Drupal-8:acquiaSearch404Disabled | Search 404 is not installed |
Drupal-8:acquiaApacheSolrFileDisabled | Apache Solr File is not installed |
Drupal-8:acquiaCiviCRMDisabled | CiviCRM is not installed |
Drupal-8:acquiaAPCDisabled | APC is not installed |
Drupal-8:acquiaLinkCheckerDisabled | Link Checker is not installed |
Drupal-8:acquiaFilefieldSourcesDisabled | Filefield Sources is not installed |
Drupal-8:acquiaWorkbenchModerationDisabled | Workbench Moderation is not installed |
Drupal-8:acquiaNodeViewCountDisabled | Node view count is not installed |
Drupal-8:acquiaAutoSlaveDisabled | AutoSlave is not installed |
Drupal-8:acquiaDBMaintenanceDisabled | DB Maintenance is not installed |
Drupal-8:acquiaLDAPDisabled | Lightweight Directory Access Protocol (LDAP) is not installed |
Acquia:CloudEdgeNoPurge | Acquia Cloud Edge Purging Enabled |
Drupal-8:StatisticsDisabled | Statistics module is not installed |
Drupal-8:NoBackupAndMigrate | Backup and Migrate is not installed |
Drupal-8:roleMemoryLimitDisabled | Role Memory Limit is not installed |
Drupal-8:memcacheStorageDisabled | Memcache Storage is not installed |
Drupal-8:DevelDisabled | Devel module is not installed |
Drupal-8:tbMegaMenuDisabled | TB Mega Menu is not installed |
Drupal-8:ipGeolocDisabled | IP Geolocation is not installed |
Drupal-8:h5pDisabled | H5P is not installed |
Drupal-8:globalFilterDisabled | Views Global Filter is not installed |
Drupal-8:ViewsUIDisabled | Views UI module is not installed |
Drupal-8:recaptchaDisabled | reCAPTCHA is not installed |
Drupal-8:SimpleTestDisabled | Simpletest module is not installed |
Drupal-8:ConfigDevelDisabled | Configuration development module is not installed |
Drupal-8:sessionAPIDisabled | Session API is not installed |
Drupal-8:PhpDisabled | PHP module is not installed |
Drupal-8:smartIPDisabled | Smart IP is not installed |
Drupal-8:KintDisabled | Kint module is not installed |
Drupal-8:DblogDisabled | Database logging is not installed |
Drupal-8:fbconnectDisabled | Facebook Connect is not installed |
Drupal-8:textSizeDisabled | Text Size is not installed |
Drupal-8:fileCacheDisabled | File Cache is not installed |
Drupal-8:WebprofilerDisabled | Webprofiler module is not installed |
Drupal-8:supercookieDisabled | Super Cookie is not installed |
Drupal-8:ShieldDisabled | Shield module is not installed |
Drupal-8:pageCacheDisabled | Page Cache module is not installed |
Drupal-8:viewsFilterHarmonizerDisabled | Views Filter Harmonizer is not installed |
Drupal-8:blockcacheAlterDisabled | Block Cache Alter is not installed |
Drupal-8:UpdateDisabled | Update module is not installed |
Drupal-8:sessionCacheDisabled | Session Cache API is not installed |
Drupal-8:NoAutomatedCron | Automated Cron module is not installed |
Parameters
Name | Type | Description | Default |
---|---|---|---|
module | string | The module to check is enabled. | null |
Tokens
Name | Type | Description | Default |
---|---|---|---|
module | string | The module to check is enabled. | null |
Source
public function audit(Sandbox $sandbox)
{
$module = $sandbox->getParameter('module');
try {
$info = $sandbox->drush(['format' => 'json'])->pmList();
}
catch (DrushFormatException $e) {
return strpos($e->getOutput(), $module . ' was not found.') !== FALSE;
}
if (!isset($info[$module])) {
return TRUE;
}
$status = strtolower($info[$module]['status']);
return ($status != 'enabled');
}
NoExperimentalCore
Generic module is disabled check.
Class: Drutiny\Plugin\Drupal8\Audit\NoExperimentalCore
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-8
Policies
These are the policies that use this class:
Name | Title |
---|---|
Drupal-8:NoExperimental | No Experimental Modules in Use |
Source
public function audit(Sandbox $sandbox)
{
$info = $sandbox->drush([
'format' => 'json',
'status' => 'Enabled',
'core',
])->pmList();
$info = array_filter($info, function ($package) {
return strpos('experimental', strtolower($package['package'])) !== FALSE;
});
if (empty($info)) {
return TRUE;
}
$sandbox->setParameter('modules', array_values($info));
return FALSE;
}
PurgePluginExists
Check a purge plugin exists.
Class: Drutiny\Plugin\Drupal8\Audit\PurgePluginExists
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-8
Policies
These are the policies that use this class:
Name | Title |
---|---|
Acquia:PurgePlugin | Acquia Purge Plugin Exists |
Parameters
Name | Type | Description | Default |
---|---|---|---|
plugin | string | The plugins to check exists | null |
Tokens
Name | Type | Description | Default |
---|---|---|---|
plugin | string | The plugins to check exists | null |
Source
public function audit(Sandbox $sandbox) {
$plugin_name = $sandbox->getParameter('plugin');
try {
$config = $sandbox->drush([
'format' => 'json',
'include-overridden' => NULL,
])->configGet('purge.plugins');
$plugins = $config['purgers'];
foreach ($plugins as $plugin) {
if ($plugin['plugin_id'] == $plugin_name) {
return TRUE;
}
}
}
catch (\Drutiny\Driver\DrushFormatException $e) {
$sandbox->setParameter('exception', $e->getMessage());
}
return FALSE;
}
PurgePluginNotExists
Check a purge plugin exists.
Class: Drutiny\Plugin\Drupal8\Audit\PurgePluginNotExists
Extends: Drutiny\Plugin\Drupal8\Audit\PurgePluginExists
Package: drutiny/plugin-drupal-8
Source
public function audit(Sandbox $sandbox) {
return !parent::audit($sandbox);
}
SettingCompare
Check a configuration is set correctly.
Class: Drutiny\Plugin\Drupal8\Audit\SettingCompare
Extends: Drutiny\Audit\AbstractComparison
Package: drutiny/plugin-drupal-8
Policies
These are the policies that use this class:
Name | Title |
---|---|
Drupal-8:MemcachedExtension | Memcache extension set |
Drupal-8:DefaultCacheMemcache | Memcache set as default cache backend |
Parameters
Name | Type | Description | Default |
---|---|---|---|
key | string | The settings key to evauate | null |
value | string | The value of the key you want to compare against. | null |
conditional_expression | string | The expression language to evaludate. See https://symfony.com/doc/current/components/expression_language/syntax.html | 'true' |
Tokens
Name | Type | Description | Default |
---|---|---|---|
key | string | The settings key to evauate | null |
value | string | The value of the key you want to compare against. | null |
reading | mixed | The value retrieve from the key in the Drupal site. | null |
conditional_expression | string | The expression language to evaludate. See https://symfony.com/doc/current/components/expression_language/syntax.html | 'true' |
Source
public function audit(Sandbox $sandbox) {
$key = $sandbox->getParameter('key');
$value = $sandbox->getParameter('value');
$settings = $sandbox->drush()->evaluate(function () {
return \Drupal\Core\Site\Settings::getAll();
});
if (!is_array($settings)){
throw new \Exception("Settings retrieved were not in a known format. Expected Array.");
}
$keys = explode('.', $key);
while ($k = array_shift($keys)) {
if (!isset($settings[$k])) {
$sandbox->logger()->info("Could not find '$k' value in $key. No such setting exists.");
return FALSE;
}
$settings = $settings[$k];
}
$reading = $settings;
$sandbox->setParameter('reading', $reading);
return $this->compare($reading, $value, $sandbox);
}
UntrustedRoles
User #1
Class: Drutiny\Plugin\Drupal8\Audit\UntrustedRoles
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-8
Policies
These are the policies that use this class:
Name | Title |
---|---|
Drupal-8:UntrustedRoles | Untrusted Roles with administrative permissions |
Source
public function audit(Sandbox $sandbox) {
$rows = $sandbox->drush()->evaluate(function ($roles) {
// Load all of Drupal's permissions so that we have access to the
// "restrict access" property.
$all_permissions = \Drupal::service('user.permissions')->getPermissions();
$rows = [];
foreach ($roles as $role) {
$untrusted_permissions = [];
// Get all permissions assigned to the untrusted role.
$roleObj = \Drupal\user\Entity\Role::load($role);
$permissions = $roleObj->getPermissions();
// Check each permission assigned to the untrusted role and determine if
// it is administrative.
// Administrative permissions will either have the "restrict access"
// property set, or the permission name contains the string "administer".
foreach ($permissions as $permission) {
if (isset($all_permissions[$permission]['restrict access']) ||
strstr($permission, 'administer') !== FALSE ) {
$untrusted_permissions[] = $all_permissions[$permission]['title'];
}
}
if (!empty($untrusted_permissions)) {
$rows[] = [
'role' => $role,
'permissions' => implode(', ', $untrusted_permissions),
];
}
}
return $rows;
}, [
'roles' => $sandbox->getParameter('untrusted_roles', ['anonymous', 'authenticated'])
]);
$sandbox->setParameter('rows', $rows);
return empty($rows) ? AUDIT::SUCCESS : AUDIT::FAIL;
}
UnusedModules
Cron last run.
Class: Drutiny\Plugin\Drupal8\Audit\UnusedModules
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-8
Policies
These are the policies that use this class:
Name | Title |
---|---|
Drupal-8:UnusedModules | Unused modules in the codebase |
Source
public function audit(Sandbox $sandbox) {
try {
$list = $sandbox->drush(['format' => 'json'])->pmInfo();
}
catch (DrushFormatException $e) {
return FALSE;
}
$installed_paths = [];
$disabled = [];
foreach ($list as $project => $info) {
if (strpos($info['package'], 'Core') !== FALSE) {
continue;
}
if ($info['type'] == 'theme') {
continue;
}
if ($info['status'] == 'enabled') {
$installed_paths[] = $info['path'];
continue;
}
$disabled[$project] = $info;
}
$unused = [];
foreach ($disabled as $project => $info) {
foreach ($installed_paths as $path) {
if (strpos($info['path'], $path) !== FALSE) {
continue 2;
}
}
$unused[] = $info['title'];
}
$sandbox->setParameter('unused_modules', $unused);
return !count($unused);
}
User1
User #1
Class: Drutiny\Plugin\Drupal8\Audit\User1
Extends: Drutiny\Audit
Package: drutiny/plugin-drupal-8
This class can remediate failed audits.
Policies
These are the policies that use this class:
Name | Title |
---|---|
Drupal-8:User1LockDown | Administrator login is locked down (uid:1) |
Parameters
Name | Type | Description | Default |
---|---|---|---|
The email the user account should be. | null | ||
blacklist | List of usernames that are not acceptable. | null | |
status | Whether the account should be enabled or disabled. | null |
Tokens
Name | Type | Description | Default |
---|---|---|---|
The email the user account should be. | null | ||
blacklist | List of usernames that are not acceptable. | null | |
status | Whether the account should be enabled or disabled. | null |
Source
public function audit(Sandbox $sandbox) {
// Get the details for user #1.
$user = $sandbox->drush(['format' => 'json'])
->userInformation(1);
$user = (object) array_pop($user);
$errors = [];
$fixups = [];
// Username.
$pattern = $sandbox->getParameter('blacklist');
if (preg_match("#${pattern}#i", $user->name)) {
$errors[] = "Username '$user->name' is too easy to guess.";
}
$sandbox->setParameter('username', $user->name);
// Email address.
$email = $sandbox->getParameter('email');
if (!empty($email) && ($email !== $user->mail)) {
$errors[] = "Email address '$user->mail' is not set correctly.";
}
// Status.
$status = (bool) $sandbox->getParameter('status');
if ($status !== (bool) $user->status) {
$errors[] = 'Status is not set correctly. Should be ' . ($user->status ? 'active' : 'inactive') . '.';
}
$sandbox->setParameter('errors', $errors);
return empty($errors) ? TRUE : Audit::WARNING;
}