abstract class MobileNumberTfa in Mobile Number 8
Same name and namespace in other branches
- 2.0.x src/Plugin/TfaValidation/MobileNumberTfa.php \Drupal\mobile_number\Plugin\TfaValidation\MobileNumberTfa
Class MobileNumberTfa is a validation and sending plugin for TFA.
@package Drupal\mobile_number
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\tfa\Plugin\TfaBasePlugin uses DependencySerializationTrait, TfaDataTrait
- class \Drupal\mobile_number\Plugin\TfaValidation\MobileNumberTfa implements TfaSendInterface, TfaValidationInterface
- class \Drupal\tfa\Plugin\TfaBasePlugin uses DependencySerializationTrait, TfaDataTrait
Expanded class hierarchy of MobileNumberTfa
File
- src/
Plugin/ TfaValidation/ MobileNumberTfa.php, line 27 - MobileNumberTfa.php
Namespace
Drupal\mobile_number\Plugin\TfaValidationView source
abstract class MobileNumberTfa extends TfaBasePlugin implements TfaValidationInterface, TfaSendInterface {
/**
* Libphonenumber Utility object.
*
* @var \Drupal\mobile_number\MobileNumberUtilInterface
*/
public $mobileNumberUtil;
/**
* Libphonenumber phone number object.
*
* @var \libphonenumber\PhoneNumber
*/
public $mobileNumber;
/**
* The Messenger service.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $messenger;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, UserDataInterface $user_data, EncryptionProfileManagerInterface $encryption_profile_manager, EncryptServiceInterface $encrypt_service, MessengerInterface $messenger) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $user_data, $encryption_profile_manager, $encrypt_service);
$this->mobileNumberUtil = \Drupal::service('mobile_number.util');
$this->messenger = $messenger;
if (!empty($context['validate_context']) && !empty($context['validate_context']['code'])) {
$this->code = $context['validate_context']['code'];
}
if (!empty($context['validate_context']) && !empty($context['validate_context']['verification_token'])) {
$this->verificationToken = $context['validate_context']['verification_token'];
}
$this->codeLength = 4;
if ($m = $this->mobileNumberUtil
->tfaAccountNumber($context['uid'])) {
try {
$this->mobileNumber = $this->mobileNumberUtil
->testMobileNumber($m);
} catch (MobileNumberException $e) {
throw new Exception("Two factor authentication failed: \n" . $e
->getMessage(), $e
->getCode());
}
}
}
/**
* {@inheritdoc}
*/
public function ready() {
return $this->mobileNumberUtil
->tfaAccountNumber($this->context['uid']) ? TRUE : FALSE;
}
/**
* {@inheritdoc}
*/
public function begin() {
if (!$this->code) {
if (!$this
->sendCode()) {
$this->messenger
->addError(t('Unable to deliver the code. Please contact support.'));
}
}
}
/**
* {@inheritdoc}
*/
public function getForm(array $form, FormStateInterface $form_state) {
$local_number = $this->mobileNumberUtil
->getLocalNumber($this->mobileNumber);
$numberClue = str_pad(substr($local_number, -3, 3), strlen($local_number), 'X', STR_PAD_LEFT);
$numberClue = substr_replace($numberClue, '-', 3, 0);
$form['code'] = [
'#type' => 'textfield',
'#title' => t('Verification Code'),
'#required' => TRUE,
'#description' => t('A verification code was sent to %clue. Enter the @length-character code sent to your device.', [
'@length' => $this->codeLength,
'%clue' => $numberClue,
]),
];
$form['actions']['#type'] = 'actions';
$form['actions']['login'] = [
'#type' => 'submit',
'#value' => t('Verify'),
];
$form['actions']['resend'] = [
'#type' => 'submit',
'#value' => t('Resend'),
'#submit' => [
'tfa_form_submit',
],
'#limit_validation_errors' => [],
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array $form, FormStateInterface $form_state) {
// If operation is resend then do not attempt to validate code.
if ($form_state['values']['op'] === $form_state['values']['resend']) {
return TRUE;
}
elseif (!$this
->verifyCode($form_state['values']['code'])) {
$this->errorMessages['code'] = t('Invalid code.');
return FALSE;
}
else {
return TRUE;
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array $form, FormStateInterface &$form_state) {
// Resend code if pushed.
if ($form_state['values']['op'] === $form_state['values']['resend']) {
if (!$this->mobileNumberUtil
->checkFlood($this->mobileNumber, 'sms')) {
$this->messenger
->addError(t('Too many verification code requests, please try again shortly.'));
}
elseif (!$this
->sendCode()) {
$this->messenger
->addError(t('Unable to deliver the code. Please contact support.'));
}
else {
$this->messenger
->addMessage(t('Hello world'));
}
return FALSE;
}
else {
return parent::submitForm($form, $form_state);
}
}
/**
* Return context for this plugin.
*/
public function getPluginContext() {
return [
'code' => $this->code,
'verification_token' => !empty($this->verificationToken) ? $this->verificationToken : '',
];
}
/**
* Send the code via the client.
*
* @return bool
* Where sending sms was successful.
*/
public function sendCode() {
$user = \Drupal::entityTypeManager()
->getStorage('user')
->load($this->context['uid']);
$this->code = $this->mobileNumberUtil
->generateVerificationCode($this->codeLength);
try {
$message = \Drupal::configFactory()
->getEditable('mobile_number.settings')
->get('tfa_message');
$message = $message ? $message : $this->mobileNumberUtil->MOBILE_NUMBER_DEFAULT_SMS_MESSAGE;
if (!($this->verificationToken = $this->mobileNumberUtil
->sendVerification($this->mobileNumber, $message, $this->code, [
'user' => $user,
]))) {
return FALSE;
}
// @todo Consider storing date_sent or date_updated to inform user.
\Drupal::logger('mobile_number_tfa')
->info('TFA validation code sent to user @uid', [
'@uid' => $this->context['uid'],
]);
return TRUE;
} catch (Exception $e) {
\Drupal::logger('mobile_number_tfa')
->error('Send message error to user @uid. Status code: @code, message: @message', [
'@uid' => $this->context['uid'],
'@code' => $e
->getCode(),
'@message' => $e
->getMessage(),
]);
return FALSE;
}
}
/**
* Verifies the given code with this session's verification token.
*
* @param string $code
* Code.
*
* @return bool
* Verification status.
*/
public function verifyCode($code) {
return $this->isValid = $this->mobileNumberUtil
->verifyCode($this->mobileNumber, $code, $this->verificationToken);
}
/**
* {@inheritdoc}
*/
public function getFallbacks() {
return $this->pluginDefinition['fallbacks'] ?: '';
}
/**
* {@inheritdoc}
*/
public function purge() {
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
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 | |
MobileNumberTfa:: |
protected | property | The Messenger service. | |
MobileNumberTfa:: |
public | property | Libphonenumber phone number object. | |
MobileNumberTfa:: |
public | property | Libphonenumber Utility object. | |
MobileNumberTfa:: |
public | function |
TFA process begin. Overrides TfaSendInterface:: |
|
MobileNumberTfa:: |
public | function | ||
MobileNumberTfa:: |
public | function |
Get TFA process form from plugin. Overrides TfaValidationInterface:: |
|
MobileNumberTfa:: |
public | function | Return context for this plugin. | |
MobileNumberTfa:: |
public | function | ||
MobileNumberTfa:: |
public | function |
Determine if the plugin can run for the current TFA context. Overrides TfaBasePlugin:: |
|
MobileNumberTfa:: |
public | function | Send the code via the client. | |
MobileNumberTfa:: |
public | function |
Submit form. Overrides TfaBasePlugin:: |
|
MobileNumberTfa:: |
public | function |
Validate form. Overrides TfaValidationInterface:: |
|
MobileNumberTfa:: |
public | function | Verifies the given code with this session's verification token. | |
MobileNumberTfa:: |
public | function |
Constructs a new Tfa plugin object. Overrides TfaBasePlugin:: |
|
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
3 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
TfaBasePlugin:: |
protected | property | Whether the code has been used before. | |
TfaBasePlugin:: |
protected | property | The user submitted code to be validated. | |
TfaBasePlugin:: |
protected | property | The allowed code length. | |
TfaBasePlugin:: |
protected | property | Encryption profile. | |
TfaBasePlugin:: |
protected | property | Encryption service. | |
TfaBasePlugin:: |
protected | property | The error for the current validation. | |
TfaBasePlugin:: |
protected | property | Whether the validation succeeded or not. | |
TfaBasePlugin:: |
protected | property | The user id. | |
TfaBasePlugin:: |
protected | property | Provides the user data service object. | |
TfaBasePlugin:: |
protected | function | Whether code has already been used. | |
TfaBasePlugin:: |
protected | function | Decrypt a encrypted string. | |
TfaBasePlugin:: |
protected | function | Encrypt a plaintext string. | |
TfaBasePlugin:: |
public | function | Get error messages suitable for form_set_error(). | |
TfaBasePlugin:: |
public | function | Get the plugin label. | |
TfaBasePlugin:: |
protected | function | Store validated code to prevent replay attack. | |
TfaBasePlugin:: |
protected | function | Validate code. | 1 |
TfaDataTrait:: |
protected | function | Deletes data stored for the current validated user account. | |
TfaDataTrait:: |
protected | function | Returns data stored for the current validated user account. | |
TfaDataTrait:: |
protected | function | Store user specific information. | |
TfaDataTrait:: |
protected | function | Get TFA data for an account. | |
TfaDataTrait:: |
public | function | Save TFA data for an account. |