saferpermissions.module in Safer Permissions 7
Disallows unwanted permissions for anonymous.
File
saferpermissions.moduleView source
<?php
/**
* @file
* Disallows unwanted permissions for anonymous.
*/
/**
* Implements hook_form_FORM_ID_alter().
*/
function saferpermissions_form_user_admin_permissions_alter(&$form, &$form_state) {
if (isset($form['checkboxes'][DRUPAL_ANONYMOUS_RID])) {
if (empty($form['checkboxes'][DRUPAL_ANONYMOUS_RID]['#process'])) {
$checkboxes_element_info = element_info('checkboxes');
$form['checkboxes'][DRUPAL_ANONYMOUS_RID]['#process'] = $checkboxes_element_info['#process'];
}
// Attach a process function which disables the checkboxes.
$form['checkboxes'][DRUPAL_ANONYMOUS_RID]['#process'][] = '_saferpermissions_anonymous_permissions_process';
// Attach a validator which makes sure that the checkbox is not checked
// even if the user checks the checkbox by removing the disabled attribute
// manually.
$form['checkboxes'][DRUPAL_ANONYMOUS_RID]['#element_validate'][] = '_saferpermissions_anonymous_permissions_element_validate';
}
}
/**
* Form element process callback.
*
* This function disables permission checkboxes on anonymous users.
*/
function _saferpermissions_anonymous_permissions_process($element) {
foreach (array_keys(saferpermissions_disallowed_permissions_anonymous()) as $permission) {
$element[$permission]['#disabled'] = TRUE;
$element[$permission]['#default_value'] = FALSE;
}
return $element;
}
/**
* Form element validation callback.
*
* This function makes sure that a disabled permission checkbox will not be
* checked.
*/
function _saferpermissions_anonymous_permissions_element_validate($element, &$form_state, $form) {
foreach (saferpermissions_disallowed_permissions_anonymous() as $permission => $title) {
if (isset($element[$permission]['#value']) && $element[$permission]['#value']) {
form_error($element[$permission], t('You cannot grant %permission to anonymous users for security reasons.', array(
'%permission' => strip_tags($title),
)));
}
}
}
/**
* Gathers the list of permission which should be banned for anonymous users.
*
* @return array
* List of permissions.
*/
function saferpermissions_disallowed_permissions_anonymous() {
$cache =& drupal_static(__FUNCTION__, NULL);
if ($cache === NULL) {
$cache = array();
$filters = array(
'_saferpermissions_is_restricted',
'_saferpermissions_is_banned',
'_saferpermissions_is_banned_word',
);
foreach (module_invoke_all('permission') as $name => $info) {
if (!_saferpermissions_is_whitelisted($name)) {
foreach ($filters as $filter) {
if ($filter($name, $info)) {
$cache[$name] = $info['title'];
break;
}
}
}
}
}
return $cache;
}
/**
* Checks if a permission is on the whitelist.
*
* @param $name
* Name of the permission.
*
* @return bool
*/
function _saferpermissions_is_whitelisted($name) {
return in_array($name, saferpermissions_permission_whitelist());
}
/**
* Checks if a permission is restricted.
*
* @param string $name
* Name of the permission.
* @param array $info
* Permission declaration.
*
* @return bool
*/
function _saferpermissions_is_restricted($name, array $info) {
return !empty($info['restrict access']);
}
/**
* Checks if a permission is on the blacklist.
*
* @param string $name
* Name of the permission.
* @param array $info
* Permission declaration.
*
* @return bool
*/
function _saferpermissions_is_banned($name, array $info) {
return in_array($name, saferpermissions_permission_blacklist());
}
/**
* Returns a list of whitelisted permissions.
*
* @return array
* List of whitelisted words.
*/
function saferpermissions_permission_whitelist() {
$cache =& drupal_static(__FUNCTION__, NULL);
if ($cache === NULL) {
$cache = module_invoke_all('saferpermissions_anonymous_permission_whitelist_info');
drupal_alter('saferpermissions_anonymous_permission_whitelist_info', $cache);
}
return $cache;
}
/**
* Returns the list of permissions which should be disabled on anonymous users.
*
* @return array
* List of disabled permissions.
*/
function saferpermissions_permission_blacklist() {
$cache =& drupal_static(__FUNCTION__, NULL);
if ($cache === NULL) {
$cache = module_invoke_all('saferpermissions_anonymous_permission_ban_info');
drupal_alter('saferpermissions_anonymous_permission_ban_info', $cache);
}
return $cache;
}
/**
* Returns a list of words.
*
* These should disable any permission on anonymous users which contains them.
*
* @return array
* List of words.
*/
function saferpermissions_permission_wordlist() {
$cache =& drupal_static(__FUNCTION__, NULL);
if ($cache === NULL) {
$cache = module_invoke_all('saferpermissions_anonymous_permission_wordlist_ban_info');
drupal_alter('saferpermissions_anonymous_permission_wordlist_ban_info', $cache);
}
return $cache;
}
/**
* Implements hook_saferpermissions_anonymous_permission_ban_info().
*/
function saferpermissions_saferpermissions_anonymous_permission_ban_info() {
$permissions = array(
// Book
'create new books',
'add content to books',
// Contextual links
'access contextual links',
// Dashboard
'access dashboard',
// Locale
'translate interface',
// Node
'access content overview',
'view revisions',
'revert revisions',
'delete revisions',
// Overlay
'access overlay',
// Path
'create url aliases',
// Shortcut
'customize shortcut links',
'switch shortcut sets',
// Statistics
'access statistics',
'view post access counter',
// System
'access administration pages',
'access site in maintenance mode',
'view the administration theme',
'access site reports',
// Toolbar
'access toolbar',
// User
'cancel account',
);
foreach (filter_formats() as $name => $format) {
if (_saferpermissions_text_format_is_forbidden($name)) {
$permissions[] = filter_permission_name($format);
}
}
return $permissions;
}
/**
* Decides if a text format is safe for anonymous.
*
* @param string $name
* Machine name of the text format.
*
* @return bool
* Returns FALSE if the text format is safe, TRUE otherwise.
*/
function _saferpermissions_text_format_is_forbidden($name) {
$filters = filter_list_format($name);
// Display any HTML as plain text.
if ($filters['filter_html_escape']->status) {
return FALSE;
}
// Limit allowed HTML tags.
if ($filters['filter_html']->status) {
// Make sure that malicious HTML tags are not enabled.
$allowed_html = $filters['filter_html']->settings['allowed_html'];
$malicious_tags = array(
'iframe',
'script',
'style',
'link',
'object',
'embed',
);
foreach ($malicious_tags as $malicious_tag) {
if (strpos($allowed_html, "<{$malicious_tag}>") !== FALSE) {
return TRUE;
}
}
return FALSE;
}
// HTML Purifier.
if (isset($filters['htmlpurifier_basic']) && $filters['htmlpurifier_basic']->status) {
return FALSE;
}
return TRUE;
}
/**
* Implements hook_saferpermissions_anonymous_permission_wordlist_ban_info().
*/
function saferpermissions_saferpermissions_anonymous_permission_wordlist_ban_info() {
return array(
'administer',
'bypass',
'migrate',
'import',
'own',
'any',
'all',
'php',
'edit terms in',
'delete terms in',
);
}
/**
* Implements hook_saferpermissions_anonymous_permission_whitelist_info().
*/
function saferpermissions_saferpermissions_anonymous_permission_whitelist_info() {
return array(
// Node
'view own unpublished content',
// Vote
'cancel own vote',
'inspect all votes',
);
}
/**
* Checks if a permission contains a blacklisted word.
*
* @param string $name
* Name of the permission.
* @param array $info
* Permission declaration.
*
* @return bool
*/
function _saferpermissions_is_banned_word($name, array $info) {
foreach (saferpermissions_permission_wordlist() as $word) {
if (preg_match('/\\b' . preg_quote($word, '/') . '\\b/im', $name)) {
return TRUE;
}
}
return FALSE;
}