Advertisement
Guest User

Untitled

a guest
Feb 25th, 2017
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.33 KB | None | 0 0
  1. diff --git a/src/Form/TfaLoginForm.php b/src/Form/TfaLoginForm.php
  2. index b21e13a..559249a 100644
  3. --- a/src/Form/TfaLoginForm.php
  4. +++ b/src/Form/TfaLoginForm.php
  5. @@ -150,12 +150,16 @@ class TfaLoginForm extends UserLoginForm {
  6. $tfa_setup_link = Url::fromRoute('tfa.overview', array(
  7. 'user' => $account->id(),
  8. ));
  9. +///////////////////////////////////////////////temp hack //////////////////////
  10. + $user_edit_link = '/user/' . $current_uid . '/edit';
  11. +
  12. $tfa_setup_link = $tfa_setup_link->toString();
  13. drupal_set_message($this->t('You are required to setup two-factor
  14. authentication <a href="@link">here.</a> You have @skipped attempts
  15. left after this you will be unable to login.', [
  16. '@skipped' => $left,
  17. - '@link' => $tfa_setup_link,
  18. + //'@link' => $tfa_setup_link,
  19. + '@link' => $user_edit_link,
  20. ]), 'error');
  21. $this->tfaSaveTfaData($account->id(), $this->userData, $tfa_data);
  22. user_login_finalize($account);
  23. @@ -273,3 +277,4 @@ class TfaLoginForm extends UserLoginForm {
  24. }
  25.  
  26. }
  27. +
  28. diff --git a/src/Plugin/TfaSetup/TfaBasicSmsSetup.php b/src/Plugin/TfaSetup/TfaBasicSmsSetup.php
  29. new file mode 100644
  30. index 0000000..c2a8664
  31. --- /dev/null
  32. +++ b/src/Plugin/TfaSetup/TfaBasicSmsSetup.php
  33. @@ -0,0 +1,141 @@
  34. +<?php
  35. +
  36. +namespace Drupal\tfa\Plugin\TfaSetup;
  37. +
  38. +use Drupal\tfa\Plugin\TfaSetupInterface;
  39. +use Drupal\tfa\Plugin\TfaValidation\TfaBasicSms;
  40. +use Drupal\Core\Url;
  41. +use Drupal\Core\Form\FormStateInterface;
  42. +use Drupal\user\Entity\User;
  43. +
  44. +/**
  45. + * @TfaSetup(
  46. + * id = "tfa_basic_sms_setup",
  47. + * label = @Translation("TFA SMS Setup"),
  48. + * description = @Translation("TFA Basic SMS Setup Plugin")
  49. + * )
  50. + */
  51. +class TfaBasicSmsSetup extends TfaBasicSms implements TfaSetupInterface {
  52. +
  53. + public function __construct(array $configuration, $plugin_id, $plugin_definition,
  54. + \Drupal\user\UserDataInterface $user_data,
  55. + \Drupal\encrypt\EncryptionProfileManagerInterface $encryption_profile_manager,
  56. + \Drupal\encrypt\EncryptServiceInterface $encrypt_service) {
  57. + parent::__construct( $configuration, $plugin_id, $plugin_definition,
  58. + $user_data,
  59. + $encryption_profile_manager,
  60. + $encrypt_service);
  61. + $this->user = User::load($this->userId);
  62. +
  63. + }
  64. +
  65. + public function begin() {
  66. + if (empty($this->code)) {
  67. + $this->code = $this->generate();
  68. + if (!$this->sendCode($this->code)) {
  69. + // @todo decide on error text
  70. + $this->errorMessages[''] = t('Unable to deliver code to that number.');
  71. + }
  72. + }
  73. + }
  74. +
  75. + /**
  76. + * {@inheritdoc}
  77. + */
  78. + public function getSetupMessages() {
  79. + return ($this->pluginDefinition['setupMessages']) ?: '';
  80. + }
  81. +
  82. + /**
  83. + * {@inheritdoc}
  84. + */
  85. + public function getOverview($params) {
  86. +
  87. + $output = [
  88. + 'heading' => [
  89. + '#theme' => 'html_tag',
  90. + '#tag' => 'h3',
  91. + '#value' => t('SMS TWILIO '),
  92. + ],
  93. + 'description' => [
  94. + '#theme' => 'html_tag',
  95. + '#tag' => 'p',
  96. + '#value' => t('Dont know yet.'),
  97. + ],
  98. + ];
  99. + if (!empty($trusted_browsers)) {
  100. +
  101. + $output['list'] = [
  102. + '#theme' => 'item_list',
  103. + '#items' => $trusted_browsers,
  104. + '#title' => t('Dont know yet.2'),
  105. + ];
  106. + }
  107. + $output['link'] = [
  108. + '#theme' => 'links',
  109. + '#links' => [
  110. + 'admin' => [
  111. + 'title' => 'Configure SMS',
  112. + 'url' => Url::fromRoute('tfa.validation.setup', [
  113. + 'user' => $params['account']->id(),
  114. + 'method' => $params['plugin_id'],
  115. + ]),
  116. + ],
  117. + ],
  118. + ];
  119. +
  120. + return $output;
  121. + }
  122. +
  123. + /**
  124. + * @copydoc TfaSetupPluginInterface::getSetupForm()
  125. + */
  126. + public function getSetupForm(array $form, FormStateInterface $form_state) {
  127. + $form['sms_code'] = array(
  128. + '#type' => 'textfield',
  129. + '#title' => t('Verification Code'),
  130. + '#required' => TRUE,
  131. + '#description' => t('Enter @length-character code sent to your device.', array('@length' => $this->codeLength)),
  132. + );
  133. + $form['actions']['verify'] = array(
  134. + '#type' => 'submit',
  135. + '#value' => t('Verify and save'),
  136. + );
  137. +
  138. + return $form;
  139. + }
  140. +
  141. + /**
  142. + * @copydoc TfaSetupPluginInterface::validateSetupForm()
  143. + */
  144. + public function validateSetupForm(array $form, FormStateInterface $form_state) {
  145. +
  146. + //if (!$this->validate($form_state['values']['sms_code'])) {
  147. + if (!$this->validate((string)$form_state->getValue('sms_code'))) {
  148. + $this->errorMessages['sms_code'] = t('Invalid code. Please try again.');
  149. + return FALSE;
  150. + }
  151. + else {
  152. + $phone_verification = $this->phone_verification_service->getPhoneVerificationByEntity($this->user, $this->mobileNumber);
  153. + $phone_verification->setStatus(TRUE)->save();
  154. + return TRUE;
  155. + }
  156. + }
  157. +
  158. + /**
  159. + * @copydoc TfaSetupPluginInterface::submitSetupForm()
  160. + */
  161. + public function submitSetupForm(array $form, FormStateInterface $form_state) {
  162. + // No submission handling required.
  163. + return TRUE;
  164. + }
  165. +
  166. + /**
  167. + * Get list of helper links for the plugin
  168. + *
  169. + * @return array List of helper links
  170. + */
  171. + public function getHelpLinks(){
  172. + return $this->pluginDefinition['help_links'];
  173. + }
  174. +}
  175. diff --git a/src/Plugin/TfaValidation/TfaBasicSms.php b/src/Plugin/TfaValidation/TfaBasicSms.php
  176. new file mode 100644
  177. index 0000000..7906508
  178. --- /dev/null
  179. +++ b/src/Plugin/TfaValidation/TfaBasicSms.php
  180. @@ -0,0 +1,277 @@
  181. +<?php
  182. +
  183. +namespace Drupal\tfa\Plugin\TfaValidation;
  184. +
  185. +use Drupal\sms\Entity\PhoneNumberSettings;
  186. +use Drupal\sms\Entity\PhoneNumberVerification;
  187. +use Drupal\sms\Exception\SmsException;
  188. +use Drupal\sms_twilio\Plugin\SmsGateway\Twilio;
  189. +use Drupal\tfa\Plugin\TfaBasePlugin;
  190. +use Drupal\tfa\Plugin\TfaValidationInterface;
  191. +use Drupal\tfa\Plugin\TfaSendInterface;
  192. +use Drupal\Core\Form\FormStateInterface;
  193. +use Drupal\user\Entity\User;
  194. +use Twilio\Rest\Client;
  195. +
  196. +/**
  197. + * @TfaValidation(
  198. + * id = "tfa_basic_sms",
  199. + * label = @Translation("TFA SMS"),
  200. + * description = @Translation("TFA SMS Validation Plugin")
  201. + * )
  202. + */
  203. +class TfaBasicSms extends TfaBasePlugin implements TfaValidationInterface {
  204. +
  205. + protected $client;
  206. +
  207. + protected $twilioNumber;
  208. +
  209. + protected $mobileNumber;
  210. +
  211. + protected $messageText;
  212. +
  213. + protected $code;
  214. +
  215. + protected $user;
  216. +
  217. + protected $userId;
  218. +
  219. + protected $status;
  220. +
  221. + protected $phone_verification_service;
  222. +
  223. + protected $phone_verification;
  224. +
  225. + public function __construct(array $configuration, $plugin_id, $plugin_definition,
  226. + \Drupal\user\UserDataInterface $user_data,
  227. + \Drupal\encrypt\EncryptionProfileManagerInterface $encryption_profile_manager,
  228. + \Drupal\encrypt\EncryptServiceInterface $encrypt_service) {
  229. +
  230. + parent::__construct($configuration, $plugin_id, $plugin_definition, $user_data, $encryption_profile_manager, $encrypt_service);
  231. +
  232. + $sid = \Drupal::config('trinity_twilio_settings')->get('sid');
  233. + $token = \Drupal::config('trinity_twilio_settings')->get('token');
  234. + $this->twilioNumber = \Drupal::config('trinity_twilio_settings')
  235. + ->get('twilioNumber');
  236. + //$this->mobileNumber = \Drupal::config('trinity_twilio_settings')->get('mobileNumber');
  237. + $this->user = $user_data;
  238. + $this->userId = $configuration['uid'];
  239. + $this->biggerUser = \Drupal\user\Entity\User::load($this->userId);
  240. + $this->mobileNumber = $this->biggerUser->get('phone_number')->value;
  241. + $this->phone_verification_service = \Drupal::service('sms.phone_number.verification');
  242. + $this->client = new Client($sid, $token);
  243. + $this->codeLength = 6;
  244. + $this->messageText = ('Verification code: ');
  245. +
  246. + $this->phone_verification = \Drupal::entityTypeManager()
  247. + ->getStorage('sms_phone_number_verification')
  248. + ->loadByProperties([
  249. + 'entity__target_id' => $this->userId,
  250. + ]);
  251. + if (isset($this->phone_verification[array_keys($this->phone_verification)[0]])) {
  252. + // id as index which gives awkward [4]=> instead of [0]=>
  253. + if (($this->phone_verification[array_keys($this->phone_verification)[0]])->get('status')->value == 0) {
  254. + $this->code = $this->phone_verification[array_keys($this->phone_verification)[0]]->get('code')->value;
  255. + }
  256. + else {
  257. + if (!empty ($this->userData->get('tfa', $configuration['uid'], 'tfa_basic_sms'))) {
  258. + $this->code = ($this->userData->get(
  259. + 'tfa',
  260. + $configuration['uid'],
  261. + 'tfa_basic_sms'
  262. + ));
  263. + }
  264. + else {
  265. + $is_admin = \Drupal::service('router.admin_context')->isAdminRoute();
  266. + if (!$is_admin && $this->ready()) {
  267. + $this->begin();
  268. + }
  269. + }
  270. + }
  271. + }
  272. + }
  273. +
  274. + /**
  275. + *
  276. + */
  277. + public function begin() {
  278. + if (!$this->code) {
  279. + $this->code = $this->generate();
  280. + if (!$this->sendCode($this->code)) {
  281. + drupal_set_message(t('Unable to deliver the code. Please contact support.'), 'error');
  282. + }
  283. + }
  284. + }
  285. +
  286. + /**
  287. + * {@inheritdoc}
  288. + */
  289. + public function ready() {
  290. +
  291. + //do we return a tfa page? false = no
  292. +
  293. + /* There are three states for the verification object.
  294. + 1) null = non-existent object. user has not yet logged in
  295. + 2) status = 0 user has been sent phone verification number
  296. + 3) status = 1 user has verified
  297. + */
  298. + $user = User::load($this->userId);
  299. + $verification = \Drupal::entityTypeManager()
  300. + ->getStorage('sms_phone_number_verification')
  301. + ->loadByProperties([
  302. + 'entity__target_id' => $this->userId,
  303. + ]);
  304. + // id as index which gives awkward [4]=> instead of [0]=>
  305. + if ($verification[array_keys($verification)[0]]) {
  306. + if ($verification[array_keys($verification)[0]]->get('status')->value == 1) {
  307. + return TRUE;
  308. + }
  309. + }
  310. + // phone was not verified - don'tshow tfa
  311. + return FALSE;
  312. + }
  313. +
  314. + public function getForm(array $form, \Drupal\Core\Form\FormStateInterface $form_state) {
  315. + $form['code'] = array(
  316. + '#type' => 'textfield',
  317. + '#title' => t('Verification Code'),
  318. + '#required' => TRUE,
  319. + '#description' => t('Enter @length-character code sent to your device.', array('@length' => $this->codeLength)),
  320. + );
  321. + $form['actions']['#type'] = 'actions';
  322. + // @todo optionally report on when code was sent/delivered.
  323. + $form['actions']['login'] = array(
  324. + '#type' => 'submit',
  325. + '#value' => t('Verify'),
  326. + );
  327. + $form['actions']['resend'] = array(
  328. + '#type' => 'submit',
  329. + '#value' => t('Resend'),
  330. + '#submit' => array('tfa_form_submit'),
  331. + '#limit_validation_errors' => array(),
  332. + );
  333. + return $form;
  334. + }
  335. +
  336. + public function validateForm(array $form, FormStateInterface $form_state) {
  337. + if ((string) $form_state->getValue('op') === (string) $form_state->getValue('resend')) {
  338. + // if sms_basic_sms exists and is blank a new code will be sent
  339. + $this->setUserData('tfa', ['tfa_basic_sms' => ''], $this->uid, $this->userData);
  340. + $form_state->setFormState(array(NULL));
  341. + return FALSE;
  342. + }
  343. + elseif (!parent::validate((string) $form_state->getValue('code'))) {
  344. + $this->errorMessages['code'] = t('Invalid code.');
  345. + return FALSE;
  346. + }
  347. + else {
  348. + // Once the code is validated do we need to clear the resend value and the code value?
  349. + $this->setUserData('tfa', ['tfa_basic_sms' => ''], $this->uid, $this->userData);
  350. + $form_state->setFormState(array(NULL));
  351. + return TRUE;
  352. + }
  353. + }
  354. +
  355. + public function submitForm(array $form, FormStateInterface &$form_state) {
  356. +
  357. + if ((string) $form_state->getValue('op') === (string) $form_state->getValue('resend')) {
  358. + $this->code = $this->generate();
  359. +
  360. + if (!$this->sendCode($this->code)) {
  361. + drupal_set_message(t('Unable to deliver the code. Please contact support.'), 'error');
  362. + }
  363. + else {
  364. + // Once the code is validated do we need to clear the resend value and the code value
  365. + $this->setUserData('tfa', ['tfa_basic_sms' => $this->code], $this->uid, $this->userData);
  366. + drupal_set_message(t('Code resent'));
  367. + }
  368. + return FALSE;
  369. + }
  370. + else {
  371. + return parent::submitForm($form, $form_state);
  372. + }
  373. + }
  374. +
  375. + /**
  376. + * Return context for this plugin.
  377. + *
  378. + * @return array
  379. + */
  380. + public function getPluginContext() {
  381. + return array(
  382. + 'code' => $this->code,
  383. + );
  384. + }
  385. +
  386. + protected function generate() {
  387. + $characters = '0123456789';
  388. + $string = '';
  389. + $max = strlen($characters) - 1;
  390. + for ($p = 0; $p < $this->codeLength; $p++) {
  391. + $string .= $characters[mt_rand(0, $max)];
  392. + }
  393. + return $string;
  394. + }
  395. +
  396. + protected function getAccountNumber() {
  397. + return $this->mobileNumber;
  398. + }
  399. +
  400. + /**
  401. + * Send the code via the client.
  402. + *
  403. + * @param string $code
  404. + * @return bool
  405. + */
  406. + protected function sendCode($code) {
  407. +
  408. + // $to = $this->getAccountNumber();
  409. + try {
  410. + // $message = $this->client->sendMessage($this->twilioNumber, $to, t($this->messageText, array('!code' => $code)));
  411. + $message = $this->client->messages->create(
  412. + $this->mobileNumber, // Text this number
  413. + array(
  414. + 'from' => $this->twilioNumber, // From a valid Twilio number
  415. + 'body' => t($this->messageText . " : " . $code)
  416. + )
  417. +
  418. + );
  419. + /*
  420. + // @todo Consider storing date_sent or date_updated to inform user.
  421. + watchdog('tfa_basic', 'Message !id sent to user !uid on @sent', array(
  422. + '@sent' => $message->date_sent,
  423. + '!id' => $message->sid,
  424. + '!uid' => $this->context['uid'],
  425. + ), WATCHDOG_INFO);
  426. + */
  427. +
  428. + $this->user->set('tfa', $this->userId, 'tfa_basic_sms', $code);
  429. + return TRUE;
  430. + } catch (SmsException $e) {
  431. + /*
  432. + // @todo Consider more detailed reporting by mapping Twilio error codes to
  433. + // messages.
  434. + watchdog('tfa_basic', 'Twilio send message error to user !uid @code @link', array(
  435. + '!uid' => $this->context['uid'],
  436. + '@code' => $e->getStatus(),
  437. + '@link' => $e->getInfo(),
  438. + ), WATCHDOG_ERROR);
  439. + */
  440. + return FALSE;
  441. + }
  442. + }
  443. +
  444. + /**
  445. + * {@inheritdoc}
  446. + */
  447. + public function isFallback() {
  448. + return TRUE;
  449. + }
  450. +
  451. + /**
  452. + * {@inheritdoc}
  453. + */
  454. + public function getFallbacks() {
  455. + return ($this->pluginDefinition['fallbacks']) ?: '';
  456. + }
  457. +}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement