View source
<?php
define('KEY_MENU_PATH', 'admin/config/system/keys');
require_once __DIR__ . '/includes/key.exception.inc';
function key_permission() {
return array(
'administer keys' => array(
'title' => t('Administer keys'),
'description' => 'Create, edit, and delete keys.',
),
);
}
function key_menu() {
$items = array();
$items[KEY_MENU_PATH] = array(
'title' => 'Keys',
'description' => 'Manage site-wide keys.',
'page callback' => 'key_configs_list',
'access arguments' => array(
'administer keys',
),
'file' => 'includes/key.admin.inc',
'type' => MENU_NORMAL_ITEM,
);
$items[KEY_MENU_PATH . '/list'] = array(
'title' => 'List keys',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items[KEY_MENU_PATH . '/add'] = array(
'title' => 'Add key',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'key_config_form',
),
'access arguments' => array(
'administer keys',
),
'file' => 'includes/key.admin.inc',
'type' => MENU_LOCAL_ACTION,
);
$items[KEY_MENU_PATH . '/manage/%key_config'] = array(
'title' => 'Edit key',
'title callback' => 'key_config_edit_title',
'title arguments' => array(
5,
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'key_config_form',
5,
),
'access arguments' => array(
'administer keys',
),
'file' => 'includes/key.admin.inc',
);
$items[KEY_MENU_PATH . '/manage/%key_config/delete'] = array(
'title' => 'Delete key',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'key_config_delete_confirm',
5,
),
'access arguments' => array(
'administer keys',
),
'file' => 'includes/key.admin.inc',
);
return $items;
}
function key_theme() {
return array(
'key_configs_list_description' => array(
'variables' => array(
'label' => NULL,
'id' => NULL,
'description' => NULL,
),
'file' => 'includes/key.admin.inc',
),
);
}
function key_ctools_plugin_directory($module, $plugin) {
if ($module == 'key' && !empty($plugin)) {
return "plugins/{$plugin}";
}
}
function key_ctools_plugin_type() {
$plugins['key_type'] = array(
'cache' => TRUE,
'cache table' => 'cache',
'process' => '_key_plugin_process',
'defaults' => array(
'label' => '',
'description' => '',
'group' => 'none',
'key value' => array(
'plugin' => 'text_field',
),
'default configuration' => NULL,
'build configuration form' => NULL,
'validate configuration form' => NULL,
'submit configuration form' => NULL,
'build delete form' => NULL,
'validate delete form' => NULL,
'submit delete form' => NULL,
'generate key value' => NULL,
'validate key value' => NULL,
),
);
$plugins['key_provider'] = array(
'cache' => TRUE,
'cache table' => 'cache',
'process' => '_key_plugin_process',
'defaults' => array(
'label' => '',
'description' => '',
'storage method' => '',
'key value' => array(
'accepted' => FALSE,
'required' => FALSE,
'editable' => FALSE,
),
'default configuration' => NULL,
'build configuration form' => NULL,
'validate configuration form' => NULL,
'submit configuration form' => NULL,
'build delete form' => NULL,
'validate delete form' => NULL,
'submit delete form' => NULL,
'get key value' => NULL,
'set key value' => NULL,
'delete key value' => NULL,
'obscure key value' => '_key_default_obscure_key_value',
'dependency callback' => NULL,
'dependency errors' => NULL,
'key value form' => NULL,
'key value obscure' => NULL,
'allow base64 encoding' => TRUE,
),
);
$plugins['key_input'] = array(
'cache' => TRUE,
'cache table' => 'cache',
'process' => '_key_plugin_process',
'defaults' => array(
'label' => '',
'description' => '',
'default configuration' => NULL,
'build configuration form' => NULL,
'validate configuration form' => NULL,
'submit configuration form' => NULL,
'build delete form' => NULL,
'validate delete form' => NULL,
'submit delete form' => NULL,
'process submitted key value' => NULL,
'process existing key value' => NULL,
),
);
return $plugins;
}
function key_element_info() {
$type['key_select'] = array(
'#input' => TRUE,
'#size' => 0,
'#multiple' => FALSE,
'#process' => array(
'_key_process_key_select',
'form_process_select',
'ajax_process_form',
),
'#theme' => 'select',
'#theme_wrappers' => array(
'form_element',
),
'#options' => array(),
'#key_filters' => array(),
'#key_description' => TRUE,
);
return $type;
}
function key_config_edit_title($config) {
return t('Edit @name key', array(
'@name' => $config['label'],
));
}
function key_config_load($id) {
return key_get_key(strtr($id, array(
'-' => '_',
)));
}
function _key_process_key_select($element) {
$options = key_get_key_names_as_options($element['#key_filters'], TRUE);
$element['#options'] = $options;
if ($element['#key_description']) {
$original_description = isset($element['#description']) ? $element['#description'] : '';
$key_description = t('Choose an available key. If the desired key is not listed, <a href="@link">create a new key</a>.', array(
'@link' => '/' . KEY_MENU_PATH . '/add',
));
$element['#description'] = $key_description . ' ' . $original_description;
}
return $element;
}
function key_get_plugins($type, $all = TRUE, $reset = FALSE) {
if (!in_array($type, _key_get_plugin_types())) {
return array();
}
if ($reset) {
_key_clear_plugin_cache($type);
}
ctools_include('plugins');
$plugins = ctools_get_plugins('key', $type);
return $all ? $plugins : array_filter($plugins, '_key_plugin_is_valid');
}
function key_get_plugins_as_options($type, $all = TRUE, $reset = FALSE) {
$plugins = key_get_plugins($type, $all, $reset);
$options = array();
foreach ($plugins as $id => $plugin) {
$options[$id] = $plugin['label'];
}
return $options;
}
function key_get_plugin($type, $plugin_id, $reset = FALSE) {
if (!in_array($type, _key_get_plugin_types())) {
return array();
}
ctools_include('plugins');
return ctools_get_plugins('key', $type, $plugin_id);
}
function key_get_keys($reset = FALSE) {
$configs =& drupal_static(__FUNCTION__);
if (!isset($configs) || $reset) {
$configs = db_query("SELECT * FROM {key_config} ORDER BY label ASC")
->fetchAllAssoc('id', PDO::FETCH_ASSOC);
foreach ($configs as $id => $config) {
foreach (array(
'key_type',
'key_provider',
'key_input',
) as $type) {
if (!empty($config[$type . '_settings'])) {
$configs[$id][$type . '_settings'] = unserialize($config[$type . '_settings']);
}
}
}
}
return $configs;
}
function key_get_keys_by_provider($key_provider_id, $reset = FALSE) {
$filtered_keys = array();
$keys = key_get_keys($reset);
foreach ($keys as $id => $key) {
if ($key['key_provider'] == $key_provider_id) {
$filtered_keys[$id] = $key;
}
}
return $filtered_keys;
}
function key_get_keys_by_type($key_type_id, $reset = FALSE) {
$filtered_keys = array();
$keys = key_get_keys($reset);
foreach ($keys as $id => $key) {
if ($key['key_type'] == $key_type_id) {
$filtered_keys[$id] = $key;
}
}
return $filtered_keys;
}
function key_get_keys_by_storage_method($storage_method, $reset = FALSE) {
$filtered_keys = array();
$keys = key_get_keys($reset);
$providers = key_get_plugins('key_provider', TRUE, $reset);
foreach ($keys as $id => $key) {
if ($providers[$key['key_provider']]['storage method'] == $storage_method) {
$filtered_keys[$id] = $key;
}
}
return $filtered_keys;
}
function key_get_keys_by_type_group($type_group, $reset = FALSE) {
$filtered_keys = array();
$keys = key_get_keys($reset);
$types = key_get_plugins('key_type', TRUE, $reset);
foreach ($keys as $id => $key) {
if ($types[$key['key_type']]['group'] == $type_group) {
$filtered_keys[$id] = $key;
}
}
return $filtered_keys;
}
function key_get_key_names_as_options($filters = array(), $reset = FALSE) {
$options = array();
$keys = key_get_keys($reset);
foreach ($filters as $index => $filter) {
switch ($index) {
case 'type':
$keys = array_intersect_key(key_get_keys_by_type($filter, $reset), $keys);
break;
case 'provider':
$keys = array_intersect_key(key_get_keys_by_provider($filter, $reset), $keys);
break;
case 'type_group':
$keys = array_intersect_key(key_get_keys_by_type_group($filter, $reset), $keys);
break;
}
}
foreach ($keys as $key) {
$key_id = $key['id'];
$key_title = $key['label'];
$options[$key_id] = (string) $key_title;
}
return $options;
}
function key_get_key($id, $reset = FALSE) {
$configs =& drupal_static(__FUNCTION__);
if (!isset($configs) || $reset) {
$configs = key_get_keys($reset);
}
if (array_key_exists($id, $configs)) {
$config = $configs[$id];
}
else {
$config = NULL;
}
return $config;
}
function key_save_key($fields, $original_config = array(), $messages = TRUE) {
foreach ($fields as $index => $field) {
if (is_array($field)) {
$fields[$index] = serialize($field);
}
}
$merge_status = db_merge('key_config')
->key(array(
'id' => $fields['id'],
))
->fields($fields)
->execute();
$key_config = key_get_key($fields['id'], TRUE);
if (empty($key_config)) {
$key_config = NULL;
}
if (!$key_config) {
if ($messages) {
$t_args = array(
'%label' => $fields['label'],
);
drupal_set_message(t('The key %label could not be saved.', $t_args), 'error');
}
return FALSE;
}
if ($messages) {
$t_args = array(
'%label' => $fields['label'],
);
switch ($merge_status) {
case MergeQuery::STATUS_INSERT:
drupal_set_message(t('The key %label has been added.', $t_args));
watchdog('key', 'Added key %label.', $t_args, WATCHDOG_NOTICE, l(t('view'), KEY_MENU_PATH . '/list'));
break;
case MergeQuery::STATUS_UPDATE:
drupal_set_message(t('The key %label has been updated.', $t_args));
watchdog('key', 'Updated key %label.', $t_args, WATCHDOG_NOTICE, l(t('view'), KEY_MENU_PATH . '/list'));
break;
}
}
if (!empty($original_config)) {
$original_key_provider = key_get_plugin('key_provider', $original_config['key_provider']);
if ($original_key_provider['key value']['accepted'] && $original_config['key_provider'] != $key_config['key_provider']) {
if ($delete_callback = ctools_plugin_get_function($original_key_provider, 'delete key value')) {
call_user_func($delete_callback, $original_config);
}
}
}
return $key_config;
}
function key_delete_key($id, $messages = TRUE) {
$config = key_get_key($id);
if (!$config) {
if ($messages) {
drupal_set_message(t('The key was not deleted because it could not be found.'));
watchdog('key', 'The key was not deleted because it could not be found.', array(), WATCHDOG_NOTICE, l(t('view'), KEY_MENU_PATH . '/list'));
}
return FALSE;
}
$key_provider = key_get_plugin('key_provider', $config['key_provider']);
if ($delete_callback = ctools_plugin_get_function($key_provider, 'delete key value')) {
call_user_func($delete_callback, $config);
}
db_delete('key_config')
->condition('id', $id)
->execute();
if ($messages) {
$t_args = array(
'%label' => $config['label'],
);
drupal_set_message(t('The key %label has been deleted.', $t_args));
watchdog('key', 'Deleted key %label.', $t_args, WATCHDOG_NOTICE);
}
$config = key_get_key($id);
return $config ? FALSE : TRUE;
}
function key_get_key_value($config) {
$keys =& drupal_static(__FUNCTION__);
if (!is_array($config)) {
$config_id = $config;
}
else {
$config_id = isset($config['id']) ? $config['id'] : '';
}
if (isset($keys[$config_id])) {
return $keys[$config_id];
}
if (!is_array($config)) {
$config = key_get_key($config_id);
}
if (!isset($config)) {
return NULL;
}
$provider = key_get_plugin('key_provider', $config['key_provider']);
$key_function = ctools_plugin_get_function($provider, 'get key value');
$key = call_user_func($key_function, $config);
$keys[$config_id] = $key;
return $key;
}
function _key_clear_plugin_cache($type = NULL) {
if ($type) {
cache_clear_all("plugins:key:{$type}", 'cache');
}
else {
cache_clear_all('plugins:key:', 'cache', TRUE);
}
}
function _key_plugin_process(&$plugin, $info) {
if ($dependency_function = ctools_plugin_get_function($plugin, 'dependency callback')) {
$plugin['dependency errors'] = call_user_func($dependency_function);
}
}
function _key_plugin_is_valid($plugin) {
if (empty($plugin['dependency errors'])) {
return TRUE;
}
else {
return FALSE;
}
}
function _key_get_plugin_types() {
return array(
'key_type',
'key_provider',
'key_input',
);
}
function _key_config_defaults() {
$key_type_id = 'authentication';
$key_provider_id = 'config';
$key_type = key_get_plugin('key_type', $key_type_id);
$key_provider = key_get_plugin('key_provider', $key_provider_id);
$key_type_defaults = ($key_type_defaults_function = ctools_plugin_get_function($key_type, 'default configuration')) ? call_user_func($key_type_defaults_function) : array();
$key_provider_defaults = ($key_provider_defaults_function = ctools_plugin_get_function($key_provider, 'default configuration')) ? call_user_func($key_provider_defaults_function) : array();
$defaults = array(
'id' => '',
'label' => '',
'description' => '',
'key_type' => $key_type_id,
'key_type_settings' => $key_type_defaults,
'key_provider' => $key_provider_id,
'key_provider_settings' => $key_provider_defaults,
);
return $defaults;
}
function _key_default_process_submitted_key_value(&$form_state) {
$processed_values = array(
'submitted' => NULL,
'processed_submitted' => NULL,
);
$key_input_settings = $form_state['values'];
$key_value_data = $form_state['storage']['key_value'];
if (isset($key_input_settings['key_value'])) {
if ($key_input_settings['key_value'] == $key_value_data['obscured']) {
$processed_values['submitted'] = $key_value_data['processed_original'];
}
else {
$processed_values['submitted'] = $key_input_settings['key_value'];
}
if (isset($key_input_settings['base64_encoded']) && $key_input_settings['base64_encoded'] == TRUE) {
$processed_values['processed_submitted'] = base64_decode($processed_values['submitted']);
}
else {
$processed_values['processed_submitted'] = $processed_values['submitted'];
}
unset($key_input_settings['key_value']);
$form_state['values'] = $key_input_settings;
}
return $processed_values;
}
function _key_default_process_existing_key_value($plugin_config, $key_value) {
if (isset($plugin_config['base64_encoded']) && $plugin_config['base64_encoded'] == TRUE) {
$processed_value = base64_encode($key_value);
}
else {
$processed_value = $key_value;
}
return $processed_value;
}
function _key_default_obscure_key_value($key_value, $options = array()) {
switch ($options['key_type_group']) {
case 'authentication':
$options['visible_right'] = 4;
$obscured_value = _key_obscure_value($key_value, $options);
break;
case 'encryption':
$options['visible_right'] = 0;
$options['fixed_length'] = 30;
$obscured_value = _key_obscure_value($key_value, $options);
break;
default:
$obscured_value = $key_value;
}
return $obscured_value;
}
function _key_obscure_value($value, $options = array()) {
$options += array(
'replacement_character' => '*',
'fixed_length' => '',
'visible_right' => 4,
);
if ($options['visible_right'] > 0) {
$visible_right_chars = drupal_substr($value, $options['visible_right'] * -1);
}
else {
$visible_right_chars = '';
}
$obscured_chars = '';
if ($options['fixed_length']) {
$obscured_chars = str_repeat($options['replacement_character'], $options['fixed_length'] - $options['visible_right']);
}
elseif (drupal_strlen($value) - $options['visible_right'] > 0) {
$obscured_chars = str_repeat($options['replacement_character'], drupal_strlen($value) - $options['visible_right']);
}
return $obscured_chars . $visible_right_chars;
}
function key_features_api() {
return array(
'key_config' => array(
'name' => 'Keys',
'file' => drupal_get_path('module', 'key') . '/includes/key_config.features.inc',
'default_hook' => 'key_default_configs',
'feature_source' => TRUE,
),
);
}