password_field.module in Password Field 7
Same filename and directory in other branches
Password Field Module
Functions for storing and displaying password fields
File
password_field.moduleView source
<?php
/**
* @file
* Password Field Module
*
* Functions for storing and displaying password fields
*/
/**
* Implements hook_field_info().
*/
function password_field_field_info() {
return array(
'password_field' => array(
'label' => t('Password'),
'description' => t('A password'),
'default_widget' => 'password_field_widget',
'default_formatter' => 'password_field_formatter',
'property_type' => 'password_field',
),
);
}
/**
* Implements hook_permission().
*/
function password_field_permission() {
return array(
'view unencrypted passwords' => array(
'title' => t('View unencrypted passwords'),
'description' => t('Allow access to unencrypted password field formatter.'),
),
);
}
/**
* Implements hook_field_formatter_info().
*/
function password_field_field_formatter_info() {
return array(
'password_field_formatter' => array(
'label' => t('Password field formatter'),
'field types' => array(
'password_field',
),
),
'unencrypted_field_formatter' => array(
'label' => t('Unencrypted password field formatter'),
'field types' => array(
'password_field',
),
),
);
}
/**
* Implements hook_field_formatter_view().
*/
function password_field_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
switch ($display['type']) {
case 'password_field_formatter':
foreach ($items as $delta => $item) {
if (!empty($item['password_field'])) {
$pw_out = '••••••••••••••••';
$element[$delta]['#markup'] = '<span>' . $pw_out . '</span>';
}
}
break;
case 'unencrypted_field_formatter':
foreach ($items as $delta => $item) {
if (!empty($item['password_field']) && user_access('view unencrypted passwords')) {
$pw_out = password_field_decrypt($item['password_field']);
$element[$delta]['#markup'] = '<span>' . $pw_out . '</span>';
}
}
break;
}
return $element;
}
/**
* Implements hook_field_widget_form().
*/
function password_field_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
$field_name = $field['field_name'];
$field_type = $field['type'];
$default_pw = $instance['default_value'][0][$field_type][$field_type];
if ($instance['widget']['type'] === 'password_field') {
$dsc_key = '#description';
$default_dsc = t('Password will remain unchanged if left blank.');
$description = empty($element[$dsc_key]) ? $default_dsc : $element[$dsc_key];
$weight = isset($element['#weight']) ? $element['#weight'] : 0;
$element['password_field'] = array(
'#type' => 'password',
'#title' => filter_xss($element['#title']),
'#description' => filter_xss($description),
'#default_value' => $default_pw,
'#required' => $element['#required'],
'#weight' => $weight,
'#delta' => $delta,
'#element_validate' => array(
'_password_field_encrypt',
),
);
}
return $element;
}
/**
* Implements hook_field_widget_error().
*/
function password_field_widget_error($element, $error, $form, &$form_state) {
switch ($error['error']) {
case 'password_field_invalid':
form_error($element, $error['message']);
break;
}
}
/**
* Implements hook_field_is_empty().
*/
function password_field_field_is_empty($item, $field) {
if (empty($item['password_field'])) {
return TRUE;
}
}
/**
* Implements hook_field_widget_info().
*/
function password_field_field_widget_info() {
return array(
'password_field' => array(
'label' => t('Password'),
'field types' => array(
'password_field',
),
),
);
}
/**
* Get field instance details.
*
* Given an element and form state, load details of the field instance
* and the entity type it is attached to.
*/
function _password_field_get_instance_details($element, $form_state) {
// Parse the element name to determine field name, language, and delta.
$pattern = '/^([^\\[]+)\\[([^\\[]+)]\\[([^\\[]+)\\]/';
if (!preg_match($pattern, $element['#name'], $matches)) {
return;
}
list($full_match, $field_name, $langcode, $delta) = $matches;
// Get the entity type and the entity itself.
$field_instance = $form_state['field'][$field_name][$langcode]['instance'];
$entity_type = $field_instance['entity_type'];
return array(
'field_name' => $field_name,
'langcode' => $langcode,
'delta' => $delta,
'entity_type' => $entity_type,
);
}
/**
* Load field value.
*
* Given an element and form state, load the current value of the field
* instance.
*/
function _password_field_load_current_value($element, $form_state) {
// Get field details.
$field_details = _password_field_get_instance_details($element, $form_state);
$entity_type = $field_details['entity_type'];
// If there is no entity, then there can't be a value.
if (empty($form_state[$entity_type])) {
return;
}
$entity = $form_state[$entity_type];
$field_name = $field_details['field_name'];
$delta = $field_details['delta'];
// Load the field instance from DB and get the value.
$pwfield = field_get_items($entity_type, $entity, $field_name);
$pwvalue = isset($pwfield[$delta]['password_field']) ? $pwfield[$delta]['password_field'] : NULL;
return $pwvalue;
}
/**
* Encrypt the password.
*/
function _password_field_encrypt($element, &$form_state) {
// If no value to encrypt, get out of here.
if (!isset($element['#value'])) {
return;
}
// If password value exists, but is empty, load old value and store that. This
// means that if the field is left blank, then the value will be unchanged.
if (empty($element['#value']) && !empty($form_state['field'])) {
$pwvalue = _password_field_load_current_value($element, $form_state);
form_set_value($element, array(
'password_field' => $pwvalue,
), $form_state);
return;
}
// If a new password value has been entered, encrypt it before saving.
if (!empty($element['#value'])) {
define('ENCRYPT_METHOD', 'AES-256-CBC');
$str = $element['#value'];
$key = md5(drupal_get_hash_salt());
// Generate the Initialization Vector.
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length(ENCRYPT_METHOD));
// Encrypt the password.
$encrypted = openssl_encrypt($str, ENCRYPT_METHOD, $key, 0, $iv);
// Save the IV with the data for the decrypt.
$value = trim(base64_encode($encrypted . '::' . $iv));
form_set_value($element, array(
'password_field' => $value,
), $form_state);
}
}
/**
* Decrypt a password string.
*/
function password_field_decrypt($str) {
$key = md5(drupal_get_hash_salt());
// Get the IV and the encrypted data.
list($encrypted_data, $iv) = explode('::', base64_decode($str), 2);
return trim(openssl_decrypt($encrypted_data, ENCRYPT_METHOD, $key, 0, $iv));
}
Functions
Name | Description |
---|---|
password_field_decrypt | Decrypt a password string. |
password_field_field_formatter_info | Implements hook_field_formatter_info(). |
password_field_field_formatter_view | Implements hook_field_formatter_view(). |
password_field_field_info | Implements hook_field_info(). |
password_field_field_is_empty | Implements hook_field_is_empty(). |
password_field_field_widget_form | Implements hook_field_widget_form(). |
password_field_field_widget_info | Implements hook_field_widget_info(). |
password_field_permission | Implements hook_permission(). |
password_field_widget_error | Implements hook_field_widget_error(). |
_password_field_encrypt | Encrypt the password. |
_password_field_get_instance_details | Get field instance details. |
_password_field_load_current_value | Load field value. |