Version Notes
Nortoneo_TwoFactorAuth v0.1.0
Download this release
Release Info
Developer | Lukasz Szczedzina |
Extension | Nortoneo_TwoFactorAuth |
Version | 0.1.0 |
Comparing to | |
See all releases |
Version 0.1.0
- app/code/community/Nortoneo/TwoFactorAuth/Block/Adminhtml/UserSettings/Edit.php +42 -0
- app/code/community/Nortoneo/TwoFactorAuth/Block/Adminhtml/UserSettings/Edit/Form.php +22 -0
- app/code/community/Nortoneo/TwoFactorAuth/Block/Adminhtml/UserSettings/Edit/Tab/Form.php +101 -0
- app/code/community/Nortoneo/TwoFactorAuth/Block/Adminhtml/UserSettings/Edit/Tabs.php +30 -0
- app/code/community/Nortoneo/TwoFactorAuth/Block/Adminhtml/UserSettings/Validate.php +33 -0
- app/code/community/Nortoneo/TwoFactorAuth/Block/Adminhtml/UserSettings/Validate/Form.php +22 -0
- app/code/community/Nortoneo/TwoFactorAuth/Block/Adminhtml/UserSettings/Validate/Tab/Form.php +62 -0
- app/code/community/Nortoneo/TwoFactorAuth/Block/Adminhtml/UserSettings/Validate/Tabs.php +29 -0
- app/code/community/Nortoneo/TwoFactorAuth/Helper/Data.php +96 -0
- app/code/community/Nortoneo/TwoFactorAuth/Model/Lib/GoogleAuthenticator.php +252 -0
- app/code/community/Nortoneo/TwoFactorAuth/Model/Observer.php +71 -0
- app/code/community/Nortoneo/TwoFactorAuth/Model/Resource/UserSettings.php +53 -0
- app/code/community/Nortoneo/TwoFactorAuth/Model/Resource/UserSettings/Collection.php +14 -0
- app/code/community/Nortoneo/TwoFactorAuth/Model/UserSettings.php +216 -0
- app/code/community/Nortoneo/TwoFactorAuth/controllers/Adminhtml/LoginController.php +54 -0
- app/code/community/Nortoneo/TwoFactorAuth/controllers/Adminhtml/UserSettingsController.php +104 -0
- app/code/community/Nortoneo/TwoFactorAuth/etc/adminhtml.xml +30 -0
- app/code/community/Nortoneo/TwoFactorAuth/etc/config.xml +90 -0
- app/code/community/Nortoneo/TwoFactorAuth/sql/nortoneo_twofactorauth_setup/install-0.1.0.php +58 -0
- app/design/adminhtml/default/default/layout/nortoneo/twofactorauth.xml +10 -0
- app/design/adminhtml/default/default/template/nortoneo/twofactorauth/login.phtml +49 -0
- app/design/adminhtml/default/default/template/nortoneo/twofactorauth/usersettings.phtml +35 -0
- app/etc/modules/Nortoneo_TwoFactorAuth.xml +9 -0
- app/locale/en_US/nortoneo/twofactorauth.csv +33 -0
- app/locale/en_US/template/email/nortoneo/twofactorauth/code.html +4 -0
- app/locale/pl_PL/nortoneo/twofactorauth.csv +33 -0
- package.xml +24 -0
app/code/community/Nortoneo/TwoFactorAuth/Block/Adminhtml/UserSettings/Edit.php
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Nortoneo_TwoFactorAuth
|
4 |
+
* @author Lukasz Szczedzina <contact@nortoneo.com>
|
5 |
+
* @website http://nortoneo.com
|
6 |
+
*/
|
7 |
+
class Nortoneo_TwoFactorAuth_Block_Adminhtml_UserSettings_Edit extends Mage_Adminhtml_Block_Widget_Form_Container
|
8 |
+
{
|
9 |
+
public function __construct()
|
10 |
+
{
|
11 |
+
$this->_objectId = 'id';
|
12 |
+
$this->_blockGroup = 'nortoneo_twofactorauth';
|
13 |
+
$this->_controller = 'adminhtml_userSettings';
|
14 |
+
$this->_mode = 'edit';
|
15 |
+
|
16 |
+
$confirmationMessage = Mage::helper('core')->jsQuoteEscape(
|
17 |
+
Mage::helper('core')->__('Are you sure? If you are using mobile app you will have to rescan QR code. For safety reasons you will have to enable protection again.')
|
18 |
+
);
|
19 |
+
$onclickJs = 'deleteConfirm(\'' . $confirmationMessage . '\', \'' . $this->getUrl('*/*/regenerateSecret') . '\');';
|
20 |
+
$this->_addButton('regenerate_secret', array(
|
21 |
+
'label' => Mage::helper('sales')->__('Regenerate secret key'),
|
22 |
+
'onclick' => $onclickJs,
|
23 |
+
));
|
24 |
+
|
25 |
+
parent::__construct();
|
26 |
+
$this->removeButton('back');
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Get form action URL
|
31 |
+
*
|
32 |
+
*/
|
33 |
+
public function getFormActionUrl()
|
34 |
+
{
|
35 |
+
return $this->getUrl('*/*/save');
|
36 |
+
}
|
37 |
+
|
38 |
+
public function getHeaderText()
|
39 |
+
{
|
40 |
+
return Mage::helper('nortoneo_twofactorauth')->__('Two Factor Authentication Settings');
|
41 |
+
}
|
42 |
+
}
|
app/code/community/Nortoneo/TwoFactorAuth/Block/Adminhtml/UserSettings/Edit/Form.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Nortoneo_TwoFactorAuth
|
4 |
+
* @author Lukasz Szczedzina <contact@nortoneo.com>
|
5 |
+
* @website http://nortoneo.com
|
6 |
+
*/
|
7 |
+
class Nortoneo_TwoFactorAuth_Block_Adminhtml_UserSettings_Edit_Form extends Mage_Adminhtml_Block_Widget_Form
|
8 |
+
{
|
9 |
+
protected function _prepareForm()
|
10 |
+
{
|
11 |
+
$form = new Varien_Data_Form(array(
|
12 |
+
'id' => 'edit_form',
|
13 |
+
'enctype' => 'multipart/form-data',
|
14 |
+
'action' => $this->getData('action'),
|
15 |
+
'method' => 'post'
|
16 |
+
));
|
17 |
+
$form->setUseContainer(true);
|
18 |
+
$this->setForm($form);
|
19 |
+
|
20 |
+
return parent::_prepareForm();
|
21 |
+
}
|
22 |
+
}
|
app/code/community/Nortoneo/TwoFactorAuth/Block/Adminhtml/UserSettings/Edit/Tab/Form.php
ADDED
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Nortoneo_TwoFactorAuth
|
4 |
+
* @author Lukasz Szczedzina <contact@nortoneo.com>
|
5 |
+
* @website http://nortoneo.com
|
6 |
+
*/
|
7 |
+
class Nortoneo_TwoFactorAuth_Block_Adminhtml_UserSettings_Edit_Tab_Form extends Mage_Adminhtml_Block_Widget_Form
|
8 |
+
implements Mage_Adminhtml_Block_Widget_Tab_Interface
|
9 |
+
{
|
10 |
+
/**
|
11 |
+
* Prepare content for tab
|
12 |
+
* @return string
|
13 |
+
*/
|
14 |
+
public function getTabLabel()
|
15 |
+
{
|
16 |
+
return Mage::helper('nortoneo_twofactorauth')->__('User Settings');
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Prepare title for tab
|
21 |
+
* @return string
|
22 |
+
*/
|
23 |
+
public function getTabTitle()
|
24 |
+
{
|
25 |
+
return $this->getTabLabel();
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Returns status flag about this tab can be showen or not
|
30 |
+
* @return true
|
31 |
+
*/
|
32 |
+
public function canShowTab()
|
33 |
+
{
|
34 |
+
return true;
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Returns status flag about this tab hidden or not
|
39 |
+
* @return true
|
40 |
+
*/
|
41 |
+
public function isHidden()
|
42 |
+
{
|
43 |
+
return false;
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @return Nortoneo_TwoFactorAuth_Model_UserSettings
|
48 |
+
*/
|
49 |
+
protected function getUserSettingsModel()
|
50 |
+
{
|
51 |
+
return Mage::helper('nortoneo_twofactorauth')->getCurrentUserSettingsModel();
|
52 |
+
}
|
53 |
+
|
54 |
+
protected function _prepareForm()
|
55 |
+
{
|
56 |
+
$helper = Mage::helper('nortoneo_twofactorauth');
|
57 |
+
$userSettingsModel = $this->getUserSettingsModel();
|
58 |
+
$form = new Varien_Data_Form();
|
59 |
+
$this->setForm($form);
|
60 |
+
$fieldset = $form->addFieldset('nortoneo_twofactorauth_usersettings', array('legend' => $helper->__('Two Factor Authentication Settings')));
|
61 |
+
|
62 |
+
$fieldset->addField('is_active', 'select', array(
|
63 |
+
'label' => $helper->__('Status'),
|
64 |
+
'title' => $helper->__('Status'),
|
65 |
+
'name' => 'is_active',
|
66 |
+
'required' => true,
|
67 |
+
'options' => array(0 => $helper->__('Disabled'), 1 => $helper->__('Enabled')),
|
68 |
+
));
|
69 |
+
|
70 |
+
$fieldset->addField('trust_last_ip', 'select', array(
|
71 |
+
'label' => $helper->__('Trust last IP address'),
|
72 |
+
'title' => $helper->__('Trust last IP address'),
|
73 |
+
'name' => 'trust_last_ip',
|
74 |
+
'required' => true,
|
75 |
+
'options' => $userSettingsModel->getTrustLastIpOptions(),
|
76 |
+
'note' => $helper->__('Ask for code only if IP has changed since last successful login?'),
|
77 |
+
));
|
78 |
+
|
79 |
+
$fieldset->addField('discrepancy', 'select', array(
|
80 |
+
'label' => $helper->__('Discrepancy'),
|
81 |
+
'title' => $helper->__('Discrepancy'),
|
82 |
+
'name' => 'discrepancy',
|
83 |
+
'required' => true,
|
84 |
+
'options' => $userSettingsModel->getDiscrepancyOptions(),
|
85 |
+
'note' => $helper->__('How long your code should be valid.'),
|
86 |
+
));
|
87 |
+
|
88 |
+
$fieldset->addField('method', 'select', array(
|
89 |
+
'label' => $helper->__('Authentication Method'),
|
90 |
+
'title' => $helper->__('Authentication Method'),
|
91 |
+
'name' => 'method',
|
92 |
+
'required' => true,
|
93 |
+
'options' => $userSettingsModel->getMethodOptions(),
|
94 |
+
'style' => 'width:400px;',
|
95 |
+
));
|
96 |
+
|
97 |
+
$form->setValues($userSettingsModel);
|
98 |
+
|
99 |
+
return parent::_prepareForm();
|
100 |
+
}
|
101 |
+
}
|
app/code/community/Nortoneo/TwoFactorAuth/Block/Adminhtml/UserSettings/Edit/Tabs.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Nortoneo_TwoFactorAuth
|
4 |
+
* @author Lukasz Szczedzina <contact@nortoneo.com>
|
5 |
+
* @website http://nortoneo.com
|
6 |
+
*/
|
7 |
+
class Nortoneo_TwoFactorAuth_Block_Adminhtml_UserSettings_Edit_Tabs extends Mage_Adminhtml_Block_Widget_Tabs
|
8 |
+
{
|
9 |
+
public function __construct()
|
10 |
+
{
|
11 |
+
parent::__construct();
|
12 |
+
$this->setId('userSettings_edit_tabs');
|
13 |
+
$this->setDestElementId('edit_form');
|
14 |
+
$this->setTitle(Mage::helper('nortoneo_twofactorauth')->__('Settings'));
|
15 |
+
}
|
16 |
+
|
17 |
+
protected function _beforeToHtml()
|
18 |
+
{
|
19 |
+
$settingsFormBlock = $this->getLayout()->createBlock('nortoneo_twofactorauth/adminhtml_userSettings_edit_tab_form');
|
20 |
+
$settingsFormBlock->setTemplate('nortoneo/twofactorauth/usersettings.phtml');
|
21 |
+
|
22 |
+
$this->addTab('form_section', array(
|
23 |
+
'label' => Mage::helper('nortoneo_twofactorauth')->__('User Settings'),
|
24 |
+
'title' => Mage::helper('nortoneo_twofactorauth')->__('User Settings'),
|
25 |
+
'content' => $settingsFormBlock->toHtml(),
|
26 |
+
));
|
27 |
+
|
28 |
+
return parent::_beforeToHtml();
|
29 |
+
}
|
30 |
+
}
|
app/code/community/Nortoneo/TwoFactorAuth/Block/Adminhtml/UserSettings/Validate.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Nortoneo_TwoFactorAuth
|
4 |
+
* @author Lukasz Szczedzina <contact@nortoneo.com>
|
5 |
+
* @website http://nortoneo.com
|
6 |
+
*/
|
7 |
+
class Nortoneo_TwoFactorAuth_Block_Adminhtml_UserSettings_Validate extends Mage_Adminhtml_Block_Widget_Form_Container
|
8 |
+
{
|
9 |
+
public function __construct()
|
10 |
+
{
|
11 |
+
$this->_objectId = 'id';
|
12 |
+
$this->_blockGroup = 'nortoneo_twofactorauth';
|
13 |
+
$this->_controller = 'adminhtml_userSettings';
|
14 |
+
$this->_mode = 'validate';
|
15 |
+
|
16 |
+
parent::__construct();
|
17 |
+
$this->removeButton('reset');
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Get form action URL
|
22 |
+
*
|
23 |
+
*/
|
24 |
+
public function getFormActionUrl()
|
25 |
+
{
|
26 |
+
return $this->getUrl('*/*/validatePost');
|
27 |
+
}
|
28 |
+
|
29 |
+
public function getHeaderText()
|
30 |
+
{
|
31 |
+
return Mage::helper('nortoneo_twofactorauth')->__('Two Factor Authentication Settings');
|
32 |
+
}
|
33 |
+
}
|
app/code/community/Nortoneo/TwoFactorAuth/Block/Adminhtml/UserSettings/Validate/Form.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Nortoneo_TwoFactorAuth
|
4 |
+
* @author Lukasz Szczedzina <contact@nortoneo.com>
|
5 |
+
* @website http://nortoneo.com
|
6 |
+
*/
|
7 |
+
class Nortoneo_TwoFactorAuth_Block_Adminhtml_UserSettings_Validate_Form extends Mage_Adminhtml_Block_Widget_Form
|
8 |
+
{
|
9 |
+
protected function _prepareForm()
|
10 |
+
{
|
11 |
+
$form = new Varien_Data_Form(array(
|
12 |
+
'id' => 'edit_form',
|
13 |
+
'enctype' => 'multipart/form-data',
|
14 |
+
'action' => $this->getData('action'),
|
15 |
+
'method' => 'post'
|
16 |
+
));
|
17 |
+
$form->setUseContainer(true);
|
18 |
+
$this->setForm($form);
|
19 |
+
|
20 |
+
return parent::_prepareForm();
|
21 |
+
}
|
22 |
+
}
|
app/code/community/Nortoneo/TwoFactorAuth/Block/Adminhtml/UserSettings/Validate/Tab/Form.php
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Nortoneo_TwoFactorAuth
|
4 |
+
* @author Lukasz Szczedzina <contact@nortoneo.com>
|
5 |
+
* @website http://nortoneo.com
|
6 |
+
*/
|
7 |
+
class Nortoneo_TwoFactorAuth_Block_Adminhtml_UserSettings_Validate_Tab_Form extends Mage_Adminhtml_Block_Widget_Form
|
8 |
+
implements Mage_Adminhtml_Block_Widget_Tab_Interface
|
9 |
+
{
|
10 |
+
/**
|
11 |
+
* Prepare content for tab
|
12 |
+
* @return string
|
13 |
+
*/
|
14 |
+
public function getTabLabel()
|
15 |
+
{
|
16 |
+
return Mage::helper('nortoneo_twofactorauth')->__('User Settings');
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Prepare title for tab
|
21 |
+
* @return string
|
22 |
+
*/
|
23 |
+
public function getTabTitle()
|
24 |
+
{
|
25 |
+
return $this->getTabLabel();
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Returns status flag about this tab can be showen or not
|
30 |
+
* @return true
|
31 |
+
*/
|
32 |
+
public function canShowTab()
|
33 |
+
{
|
34 |
+
return true;
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Returns status flag about this tab hidden or not
|
39 |
+
* @return true
|
40 |
+
*/
|
41 |
+
public function isHidden()
|
42 |
+
{
|
43 |
+
return false;
|
44 |
+
}
|
45 |
+
|
46 |
+
protected function _prepareForm()
|
47 |
+
{
|
48 |
+
$helper = Mage::helper('nortoneo_twofactorauth');
|
49 |
+
$form = new Varien_Data_Form();
|
50 |
+
$this->setForm($form);
|
51 |
+
$fieldset = $form->addFieldset('nortoneo_twofactorauth_usersettings', array('legend' => $helper->__('Two Factor Authentication Validation')));
|
52 |
+
|
53 |
+
$fieldset->addField('code', 'text', array(
|
54 |
+
'label' => $helper->__('Authentication Code'),
|
55 |
+
'title' => $helper->__('Authentication Code'),
|
56 |
+
'name' => 'code',
|
57 |
+
'required' => true,
|
58 |
+
));
|
59 |
+
|
60 |
+
return parent::_prepareForm();
|
61 |
+
}
|
62 |
+
}
|
app/code/community/Nortoneo/TwoFactorAuth/Block/Adminhtml/UserSettings/Validate/Tabs.php
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Nortoneo_TwoFactorAuth
|
4 |
+
* @author Lukasz Szczedzina <contact@nortoneo.com>
|
5 |
+
* @website http://nortoneo.com
|
6 |
+
*/
|
7 |
+
class Nortoneo_TwoFactorAuth_Block_Adminhtml_UserSettings_Validate_Tabs extends Mage_Adminhtml_Block_Widget_Tabs
|
8 |
+
{
|
9 |
+
public function __construct()
|
10 |
+
{
|
11 |
+
parent::__construct();
|
12 |
+
$this->setId('userSettings_validate_tabs');
|
13 |
+
$this->setDestElementId('edit_form');
|
14 |
+
$this->setTitle(Mage::helper('nortoneo_twofactorauth')->__('Settings'));
|
15 |
+
}
|
16 |
+
|
17 |
+
protected function _beforeToHtml()
|
18 |
+
{
|
19 |
+
$settingsFormBlock = $this->getLayout()->createBlock('nortoneo_twofactorauth/adminhtml_userSettings_validate_tab_form');
|
20 |
+
|
21 |
+
$this->addTab('form_section', array(
|
22 |
+
'label' => Mage::helper('nortoneo_twofactorauth')->__('Code validation'),
|
23 |
+
'title' => Mage::helper('nortoneo_twofactorauth')->__('Code validation'),
|
24 |
+
'content' => $settingsFormBlock->toHtml(),
|
25 |
+
));
|
26 |
+
|
27 |
+
return parent::_beforeToHtml();
|
28 |
+
}
|
29 |
+
}
|
app/code/community/Nortoneo/TwoFactorAuth/Helper/Data.php
ADDED
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Nortoneo_TwoFactorAuth
|
4 |
+
* @author Lukasz Szczedzina <contact@nortoneo.com>
|
5 |
+
* @website http://nortoneo.com
|
6 |
+
*/
|
7 |
+
class Nortoneo_TwoFactorAuth_Helper_Data extends Mage_Core_Helper_Abstract
|
8 |
+
{
|
9 |
+
protected $currentUserSettingsModel;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @return Nortoneo_TwoFactorAuth_Model_UserSettings
|
13 |
+
*/
|
14 |
+
public function getCurrentUserSettingsModel()
|
15 |
+
{
|
16 |
+
if ($this->currentUserSettingsModel === null) {
|
17 |
+
$user = Mage::getSingleton('admin/session')->getUser();
|
18 |
+
if (!$user) {
|
19 |
+
Mage::throwException('Cant load user model.');
|
20 |
+
}
|
21 |
+
$userId = $user->getId();
|
22 |
+
/** @var Nortoneo_TwoFactorAuth_Model_UserSettings $userSettingsModel */
|
23 |
+
$userSettingsModel = Mage::getResourceModel('nortoneo_twofactorauth/userSettings_collection')
|
24 |
+
->addFieldToFilter('user_id', $userId)
|
25 |
+
->getFirstItem();
|
26 |
+
$userSettingsModel->afterLoad();
|
27 |
+
if (!$userSettingsModel->getId()) {
|
28 |
+
$data = array(
|
29 |
+
'is_active' => 0,
|
30 |
+
'secret' => $userSettingsModel->generateSecret(),
|
31 |
+
'user_id' => $userId,
|
32 |
+
'method' => Nortoneo_TwoFactorAuth_Model_UserSettings::TWO_FACTOR_AUTH_METHOD_EMAIL,
|
33 |
+
'trust_last_ip' => Nortoneo_TwoFactorAuth_Model_UserSettings::TWO_FACTOR_AUTH_TRUST_LAST_IP_NO,
|
34 |
+
'discrepancy' => 4, //2 minutes
|
35 |
+
'last_ip' => Mage::helper('core/http')->getRemoteAddr()
|
36 |
+
);
|
37 |
+
$userSettingsModel->setData($data);
|
38 |
+
$userSettingsModel->save();
|
39 |
+
}
|
40 |
+
$this->currentUserSettingsModel = $userSettingsModel;
|
41 |
+
}
|
42 |
+
|
43 |
+
return $this->currentUserSettingsModel;
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @return bool
|
48 |
+
*/
|
49 |
+
public function isCurrentUserForAuthentication()
|
50 |
+
{
|
51 |
+
$session = Mage::getSingleton('admin/session');
|
52 |
+
if (!$session->isLoggedIn()) {
|
53 |
+
return false;
|
54 |
+
}
|
55 |
+
|
56 |
+
$authSettings = $this->getCurrentUserSettingsModel();
|
57 |
+
if (!$authSettings->getIsActive()) {
|
58 |
+
return false;
|
59 |
+
}
|
60 |
+
|
61 |
+
$currentIp = Mage::helper('core/http')->getRemoteAddr();
|
62 |
+
if ($authSettings->getTrustLastIp() && $authSettings->getLastIp() == $currentIp) {
|
63 |
+
return false;
|
64 |
+
}
|
65 |
+
|
66 |
+
if ($this->isCurrentUserValidated()) {
|
67 |
+
return false;
|
68 |
+
}
|
69 |
+
|
70 |
+
return true;
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* @return bool
|
75 |
+
*/
|
76 |
+
public function isCurrentUserValidated()
|
77 |
+
{
|
78 |
+
$session = Mage::getSingleton('admin/session');
|
79 |
+
if (!$session->isLoggedIn()) {
|
80 |
+
return false;
|
81 |
+
}
|
82 |
+
|
83 |
+
return (bool)$session->getData('two_factor_auth_validated');
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* @param bool $status
|
88 |
+
*/
|
89 |
+
public function setCurrentUserValidated($status)
|
90 |
+
{
|
91 |
+
$session = Mage::getSingleton('admin/session');
|
92 |
+
if ($session->isLoggedIn()) {
|
93 |
+
$session->setData('two_factor_auth_validated', (bool)$status);
|
94 |
+
}
|
95 |
+
}
|
96 |
+
}
|
app/code/community/Nortoneo/TwoFactorAuth/Model/Lib/GoogleAuthenticator.php
ADDED
@@ -0,0 +1,252 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* PHP Class for handling Google Authenticator 2-factor authentication.
|
5 |
+
*
|
6 |
+
* @author Michael Kliewe
|
7 |
+
* @copyright 2012 Michael Kliewe
|
8 |
+
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
9 |
+
*
|
10 |
+
* @link http://www.phpgangsta.de/
|
11 |
+
*/
|
12 |
+
class Nortoneo_TwoFactorAuth_Model_Lib_GoogleAuthenticator
|
13 |
+
{
|
14 |
+
protected $_codeLength = 6;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Create new secret.
|
18 |
+
* 16 characters, randomly chosen from the allowed base32 characters.
|
19 |
+
*
|
20 |
+
* @param int $secretLength
|
21 |
+
*
|
22 |
+
* @return string
|
23 |
+
*/
|
24 |
+
public function createSecret($secretLength = 16)
|
25 |
+
{
|
26 |
+
$validChars = $this->_getBase32LookupTable();
|
27 |
+
|
28 |
+
// Valid secret lengths are 80 to 640 bits
|
29 |
+
if ($secretLength < 16 || $secretLength > 128) {
|
30 |
+
throw new Exception('Bad secret length');
|
31 |
+
}
|
32 |
+
$secret = '';
|
33 |
+
$rnd = false;
|
34 |
+
if (function_exists('random_bytes')) {
|
35 |
+
$rnd = random_bytes($secretLength);
|
36 |
+
} elseif (function_exists('mcrypt_create_iv')) {
|
37 |
+
$rnd = mcrypt_create_iv($secretLength, MCRYPT_DEV_URANDOM);
|
38 |
+
} elseif (function_exists('openssl_random_pseudo_bytes')) {
|
39 |
+
$rnd = openssl_random_pseudo_bytes($secretLength, $cryptoStrong);
|
40 |
+
if (!$cryptoStrong) {
|
41 |
+
$rnd = false;
|
42 |
+
}
|
43 |
+
}
|
44 |
+
if ($rnd !== false) {
|
45 |
+
for ($i = 0; $i < $secretLength; ++$i) {
|
46 |
+
$secret .= $validChars[ord($rnd[$i]) & 31];
|
47 |
+
}
|
48 |
+
} else {
|
49 |
+
throw new Exception('No source of secure random');
|
50 |
+
}
|
51 |
+
|
52 |
+
return $secret;
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Calculate the code, with given secret and point in time.
|
57 |
+
*
|
58 |
+
* @param string $secret
|
59 |
+
* @param int|null $timeSlice
|
60 |
+
*
|
61 |
+
* @return string
|
62 |
+
*/
|
63 |
+
public function getCode($secret, $timeSlice = null)
|
64 |
+
{
|
65 |
+
if ($timeSlice === null) {
|
66 |
+
$timeSlice = floor(time() / 30);
|
67 |
+
}
|
68 |
+
|
69 |
+
$secretkey = $this->_base32Decode($secret);
|
70 |
+
|
71 |
+
// Pack time into binary string
|
72 |
+
$time = chr(0).chr(0).chr(0).chr(0).pack('N*', $timeSlice);
|
73 |
+
// Hash it with users secret key
|
74 |
+
$hm = hash_hmac('SHA1', $time, $secretkey, true);
|
75 |
+
// Use last nipple of result as index/offset
|
76 |
+
$offset = ord(substr($hm, -1)) & 0x0F;
|
77 |
+
// grab 4 bytes of the result
|
78 |
+
$hashpart = substr($hm, $offset, 4);
|
79 |
+
|
80 |
+
// Unpak binary value
|
81 |
+
$value = unpack('N', $hashpart);
|
82 |
+
$value = $value[1];
|
83 |
+
// Only 32 bits
|
84 |
+
$value = $value & 0x7FFFFFFF;
|
85 |
+
|
86 |
+
$modulo = pow(10, $this->_codeLength);
|
87 |
+
|
88 |
+
return str_pad($value % $modulo, $this->_codeLength, '0', STR_PAD_LEFT);
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Get QR-Code URL for image, from google charts.
|
93 |
+
*
|
94 |
+
* @param string $name
|
95 |
+
* @param string $secret
|
96 |
+
* @param string $title
|
97 |
+
* @param array $params
|
98 |
+
*
|
99 |
+
* @return string
|
100 |
+
*/
|
101 |
+
public function getQRCodeGoogleUrl($name, $secret, $title = null, $params = array())
|
102 |
+
{
|
103 |
+
$width = !empty($params['width']) && (int) $params['width'] > 0 ? (int) $params['width'] : 200;
|
104 |
+
$height = !empty($params['height']) && (int) $params['height'] > 0 ? (int) $params['height'] : 200;
|
105 |
+
$level = !empty($params['level']) && array_search($params['level'], array('L', 'M', 'Q', 'H')) !== false ? $params['level'] : 'M';
|
106 |
+
|
107 |
+
$urlencoded = urlencode('otpauth://totp/'.$name.'?secret='.$secret.'');
|
108 |
+
if (isset($title)) {
|
109 |
+
$urlencoded .= urlencode('&issuer='.urlencode($title));
|
110 |
+
}
|
111 |
+
|
112 |
+
return 'https://chart.googleapis.com/chart?chs='.$width.'x'.$height.'&chld='.$level.'|0&cht=qr&chl='.$urlencoded.'';
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Check if the code is correct. This will accept codes starting from $discrepancy*30sec ago to $discrepancy*30sec from now.
|
117 |
+
*
|
118 |
+
* @param string $secret
|
119 |
+
* @param string $code
|
120 |
+
* @param int $discrepancy This is the allowed time drift in 30 second units (8 means 4 minutes before or after)
|
121 |
+
* @param int|null $currentTimeSlice time slice if we want use other that time()
|
122 |
+
*
|
123 |
+
* @return bool
|
124 |
+
*/
|
125 |
+
public function verifyCode($secret, $code, $discrepancy = 1, $currentTimeSlice = null)
|
126 |
+
{
|
127 |
+
if ($currentTimeSlice === null) {
|
128 |
+
$currentTimeSlice = floor(time() / 30);
|
129 |
+
}
|
130 |
+
|
131 |
+
if (strlen($code) != 6) {
|
132 |
+
return false;
|
133 |
+
}
|
134 |
+
|
135 |
+
for ($i = -$discrepancy; $i <= $discrepancy; ++$i) {
|
136 |
+
$calculatedCode = $this->getCode($secret, $currentTimeSlice + $i);
|
137 |
+
if ($this->timingSafeEquals($calculatedCode, $code)) {
|
138 |
+
return true;
|
139 |
+
}
|
140 |
+
}
|
141 |
+
|
142 |
+
return false;
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Set the code length, should be >=6.
|
147 |
+
*
|
148 |
+
* @param int $length
|
149 |
+
*
|
150 |
+
* @return PHPGangsta_GoogleAuthenticator
|
151 |
+
*/
|
152 |
+
public function setCodeLength($length)
|
153 |
+
{
|
154 |
+
$this->_codeLength = $length;
|
155 |
+
|
156 |
+
return $this;
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Helper class to decode base32.
|
161 |
+
*
|
162 |
+
* @param $secret
|
163 |
+
*
|
164 |
+
* @return bool|string
|
165 |
+
*/
|
166 |
+
protected function _base32Decode($secret)
|
167 |
+
{
|
168 |
+
if (empty($secret)) {
|
169 |
+
return '';
|
170 |
+
}
|
171 |
+
|
172 |
+
$base32chars = $this->_getBase32LookupTable();
|
173 |
+
$base32charsFlipped = array_flip($base32chars);
|
174 |
+
|
175 |
+
$paddingCharCount = substr_count($secret, $base32chars[32]);
|
176 |
+
$allowedValues = array(6, 4, 3, 1, 0);
|
177 |
+
if (!in_array($paddingCharCount, $allowedValues)) {
|
178 |
+
return false;
|
179 |
+
}
|
180 |
+
for ($i = 0; $i < 4; ++$i) {
|
181 |
+
if ($paddingCharCount == $allowedValues[$i] &&
|
182 |
+
substr($secret, -($allowedValues[$i])) != str_repeat($base32chars[32], $allowedValues[$i])) {
|
183 |
+
return false;
|
184 |
+
}
|
185 |
+
}
|
186 |
+
$secret = str_replace('=', '', $secret);
|
187 |
+
$secret = str_split($secret);
|
188 |
+
$binaryString = '';
|
189 |
+
for ($i = 0; $i < count($secret); $i = $i + 8) {
|
190 |
+
$x = '';
|
191 |
+
if (!in_array($secret[$i], $base32chars)) {
|
192 |
+
return false;
|
193 |
+
}
|
194 |
+
for ($j = 0; $j < 8; ++$j) {
|
195 |
+
$x .= str_pad(base_convert(@$base32charsFlipped[@$secret[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
|
196 |
+
}
|
197 |
+
$eightBits = str_split($x, 8);
|
198 |
+
for ($z = 0; $z < count($eightBits); ++$z) {
|
199 |
+
$binaryString .= (($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48) ? $y : '';
|
200 |
+
}
|
201 |
+
}
|
202 |
+
|
203 |
+
return $binaryString;
|
204 |
+
}
|
205 |
+
|
206 |
+
/**
|
207 |
+
* Get array with all 32 characters for decoding from/encoding to base32.
|
208 |
+
*
|
209 |
+
* @return array
|
210 |
+
*/
|
211 |
+
protected function _getBase32LookupTable()
|
212 |
+
{
|
213 |
+
return array(
|
214 |
+
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 7
|
215 |
+
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
|
216 |
+
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
|
217 |
+
'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
|
218 |
+
'=', // padding char
|
219 |
+
);
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* A timing safe equals comparison
|
224 |
+
* more info here: http://blog.ircmaxell.com/2014/11/its-all-about-time.html.
|
225 |
+
*
|
226 |
+
* @param string $safeString The internal (safe) value to be checked
|
227 |
+
* @param string $userString The user submitted (unsafe) value
|
228 |
+
*
|
229 |
+
* @return bool True if the two strings are identical
|
230 |
+
*/
|
231 |
+
private function timingSafeEquals($safeString, $userString)
|
232 |
+
{
|
233 |
+
if (function_exists('hash_equals')) {
|
234 |
+
return hash_equals($safeString, $userString);
|
235 |
+
}
|
236 |
+
$safeLen = strlen($safeString);
|
237 |
+
$userLen = strlen($userString);
|
238 |
+
|
239 |
+
if ($userLen != $safeLen) {
|
240 |
+
return false;
|
241 |
+
}
|
242 |
+
|
243 |
+
$result = 0;
|
244 |
+
|
245 |
+
for ($i = 0; $i < $userLen; ++$i) {
|
246 |
+
$result |= (ord($safeString[$i]) ^ ord($userString[$i]));
|
247 |
+
}
|
248 |
+
|
249 |
+
// They are only identical strings if $result is exactly 0...
|
250 |
+
return $result === 0;
|
251 |
+
}
|
252 |
+
}
|
app/code/community/Nortoneo/TwoFactorAuth/Model/Observer.php
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @package Nortoneo_TwoFactorAuth
|
5 |
+
* @author Lukasz Szczedzina <contact@nortoneo.com>
|
6 |
+
* @website http://nortoneo.com
|
7 |
+
*/
|
8 |
+
class Nortoneo_TwoFactorAuth_Model_Observer
|
9 |
+
{
|
10 |
+
/**
|
11 |
+
* @param $observer
|
12 |
+
*/
|
13 |
+
public function processAuthentication($observer)
|
14 |
+
{
|
15 |
+
/** @var Mage_Core_Controller_Request_Http $request */
|
16 |
+
$request = Mage::app()->getRequest();
|
17 |
+
if ($this->isRequestAlwaysAllowed($request)) {
|
18 |
+
return;
|
19 |
+
}
|
20 |
+
|
21 |
+
$helper = Mage::helper('nortoneo_twofactorauth');
|
22 |
+
if (!$helper->isCurrentUserForAuthentication()) {
|
23 |
+
return;
|
24 |
+
}
|
25 |
+
|
26 |
+
/** @var Nortoneo_TwoFactorAuth_Model_UserSettings $authSettings */
|
27 |
+
$authSettings = Mage::helper('nortoneo_twofactorauth')->getCurrentUserSettingsModel();
|
28 |
+
if ($authSettings->isCodeByEmailEnabled()) {
|
29 |
+
$url = Mage::helper("adminhtml")->getUrl('nortoneo_twofactorauth/login/resend');
|
30 |
+
} else {
|
31 |
+
$url = Mage::helper("adminhtml")->getUrl('nortoneo_twofactorauth/login');
|
32 |
+
}
|
33 |
+
|
34 |
+
$response = Mage::app()->getResponse();
|
35 |
+
$response->setRedirect($url);
|
36 |
+
$response->sendResponse();
|
37 |
+
/** @var $controllerAction Mage_Core_Controller_Varien_Action */
|
38 |
+
$controllerAction = $observer->getData('controller_action');
|
39 |
+
$controllerAction->setFlag(
|
40 |
+
$controllerAction->getRequest()->getActionName(),
|
41 |
+
Mage_Core_Controller_Varien_Action::FLAG_NO_DISPATCH,
|
42 |
+
true
|
43 |
+
);
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @param Mage_Core_Controller_Request_Http $request
|
48 |
+
* @return bool
|
49 |
+
*/
|
50 |
+
protected function isRequestAlwaysAllowed(Mage_Core_Controller_Request_Http $request)
|
51 |
+
{
|
52 |
+
$controller = $request->getControllerName();
|
53 |
+
$module = $request->getModuleName();
|
54 |
+
$action = $request->getActionName();
|
55 |
+
|
56 |
+
if ($module == 'nortoneo_twofactorauth' && $controller == 'login') {
|
57 |
+
return true;
|
58 |
+
} elseif ($module == 'admin' && $controller == 'index' && in_array($action, array(
|
59 |
+
'login',
|
60 |
+
'logout',
|
61 |
+
'forgotpassword',
|
62 |
+
'resetPassword',
|
63 |
+
'resetPasswordPost'
|
64 |
+
))
|
65 |
+
) {
|
66 |
+
return true;
|
67 |
+
}
|
68 |
+
|
69 |
+
return false;
|
70 |
+
}
|
71 |
+
}
|
app/code/community/Nortoneo/TwoFactorAuth/Model/Resource/UserSettings.php
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Nortoneo_TwoFactorAuth
|
4 |
+
* @author Lukasz Szczedzina <contact@nortoneo.com>
|
5 |
+
* @website http://nortoneo.com
|
6 |
+
*/
|
7 |
+
class Nortoneo_TwoFactorAuth_Model_Resource_UserSettings extends Mage_Core_Model_Resource_Db_Abstract
|
8 |
+
{
|
9 |
+
protected $encryptionModel;
|
10 |
+
|
11 |
+
protected function _construct()
|
12 |
+
{
|
13 |
+
$this->_init('nortoneo_twofactorauth/userSettings', 'settings_id');
|
14 |
+
}
|
15 |
+
|
16 |
+
protected function _beforeSave(Mage_Core_Model_Abstract $object)
|
17 |
+
{
|
18 |
+
$secret = $object->getSecret();
|
19 |
+
$object->setSecret($this->encrypt($secret));
|
20 |
+
}
|
21 |
+
|
22 |
+
protected function _afterSave(Mage_Core_Model_Abstract $object)
|
23 |
+
{
|
24 |
+
$secret = $object->getSecret();
|
25 |
+
$object->setSecret($this->decrypt($secret));
|
26 |
+
}
|
27 |
+
|
28 |
+
protected function _afterLoad(Mage_Core_Model_Abstract $object)
|
29 |
+
{
|
30 |
+
$secret = $object->getSecret();
|
31 |
+
$object->setSecret($this->decrypt($secret));
|
32 |
+
}
|
33 |
+
|
34 |
+
protected function encrypt($value)
|
35 |
+
{
|
36 |
+
return $this->getEncryptionModel()->encrypt($value);
|
37 |
+
}
|
38 |
+
|
39 |
+
protected function decrypt($value)
|
40 |
+
{
|
41 |
+
return $this->getEncryptionModel()->decrypt($value);
|
42 |
+
}
|
43 |
+
|
44 |
+
protected function getEncryptionModel()
|
45 |
+
{
|
46 |
+
if ($this->encryptionModel === null) {
|
47 |
+
$this->encryptionModel = Mage::getModel('core/encryption');
|
48 |
+
}
|
49 |
+
|
50 |
+
return $this->encryptionModel;
|
51 |
+
}
|
52 |
+
|
53 |
+
}
|
app/code/community/Nortoneo/TwoFactorAuth/Model/Resource/UserSettings/Collection.php
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Nortoneo_TwoFactorAuth
|
4 |
+
* @author Lukasz Szczedzina <contact@nortoneo.com>
|
5 |
+
* @website http://nortoneo.com
|
6 |
+
*/
|
7 |
+
class Nortoneo_TwoFactorAuth_Model_Resource_UserSettings_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
|
8 |
+
{
|
9 |
+
protected function _construct()
|
10 |
+
{
|
11 |
+
$this->_init('nortoneo_twofactorauth/userSettings');
|
12 |
+
}
|
13 |
+
|
14 |
+
}
|
app/code/community/Nortoneo/TwoFactorAuth/Model/UserSettings.php
ADDED
@@ -0,0 +1,216 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Nortoneo_TwoFactorAuth
|
4 |
+
* @author Lukasz Szczedzina <contact@nortoneo.com>
|
5 |
+
* @website http://nortoneo.com
|
6 |
+
*/
|
7 |
+
class Nortoneo_TwoFactorAuth_Model_UserSettings extends Mage_Core_Model_Abstract
|
8 |
+
{
|
9 |
+
const TWO_FACTOR_AUTH_METHOD_EMAIL = 0;
|
10 |
+
const TWO_FACTOR_AUTH_METHOD_APP = 1;
|
11 |
+
|
12 |
+
const TWO_FACTOR_AUTH_TRUST_LAST_IP_NO = 0;
|
13 |
+
const TWO_FACTOR_AUTH_TRUST_LAST_IP_YES = 1;
|
14 |
+
|
15 |
+
const TWO_FACTOR_AUTH_CODE_EMAIL_TEMPLATE = 'nortoneo_twofactorauth_code';
|
16 |
+
const TWO_FACTOR_AUTH_CODE_EMAIL_IDENTITY = 'general';
|
17 |
+
|
18 |
+
|
19 |
+
protected $authenticator;
|
20 |
+
|
21 |
+
protected function _construct()
|
22 |
+
{
|
23 |
+
$this->_init('nortoneo_twofactorauth/userSettings');
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @param string $code
|
28 |
+
* @return bool
|
29 |
+
*/
|
30 |
+
public function verifyCode($code)
|
31 |
+
{
|
32 |
+
$secret = $this->getSecret();
|
33 |
+
if (empty($secret)) {
|
34 |
+
return false;
|
35 |
+
}
|
36 |
+
|
37 |
+
$discrepancy = (int)$this->getDiscrepancy();
|
38 |
+
|
39 |
+
return $this->getAuthenticator()->verifyCode($secret, $code, $discrepancy);
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @return bool|string
|
44 |
+
*/
|
45 |
+
public function getCurrentCode()
|
46 |
+
{
|
47 |
+
$secret = $this->getSecret();
|
48 |
+
if (empty($secret)) {
|
49 |
+
return false;
|
50 |
+
}
|
51 |
+
|
52 |
+
return $this->getAuthenticator()->getCode($secret);
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* @param int $width
|
57 |
+
* @param int $height
|
58 |
+
* @return bool|string
|
59 |
+
*/
|
60 |
+
public function getQRCodeGoogleUrl($width = 250, $height = 250)
|
61 |
+
{
|
62 |
+
$secret = $this->getSecret();
|
63 |
+
if (empty($secret)) {
|
64 |
+
return false;
|
65 |
+
}
|
66 |
+
$title = $this->getTitleForQRCode();
|
67 |
+
$name = $this->getNameForQRCode();
|
68 |
+
$params = array(
|
69 |
+
'width' => $width,
|
70 |
+
'height' => $height
|
71 |
+
);
|
72 |
+
|
73 |
+
return $this->getAuthenticator()->getQRCodeGoogleUrl($name, $secret, $title, $params);
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* @param int $secretLength
|
78 |
+
* @return string
|
79 |
+
*/
|
80 |
+
public function generateSecret($secretLength = 16)
|
81 |
+
{
|
82 |
+
return $this->getAuthenticator()->createSecret($secretLength);
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* @return array
|
87 |
+
*/
|
88 |
+
public function getMethodOptions()
|
89 |
+
{
|
90 |
+
$helper = Mage::helper('nortoneo_twofactorauth');
|
91 |
+
$userEmail = $this->getUser()->getEmail();
|
92 |
+
|
93 |
+
return array(
|
94 |
+
self::TWO_FACTOR_AUTH_METHOD_EMAIL => $helper->__('Send me codes by e-mail (%s)', $userEmail),
|
95 |
+
self::TWO_FACTOR_AUTH_METHOD_APP => $helper->__('I will use mobile application')
|
96 |
+
);
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* @return array
|
101 |
+
*/
|
102 |
+
public function getDiscrepancyOptions()
|
103 |
+
{
|
104 |
+
$helper = Mage::helper('nortoneo_twofactorauth');
|
105 |
+
|
106 |
+
$options = array();
|
107 |
+
for ($i = 1; $i < 31; $i++) {
|
108 |
+
$seconds = $i * 30;
|
109 |
+
$options[$i] = $helper->__('%s seconds', $seconds);
|
110 |
+
}
|
111 |
+
|
112 |
+
return $options;
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* @return array
|
117 |
+
*/
|
118 |
+
public function getTrustLastIpOptions()
|
119 |
+
{
|
120 |
+
$helper = Mage::helper('nortoneo_twofactorauth');
|
121 |
+
|
122 |
+
return array(
|
123 |
+
self::TWO_FACTOR_AUTH_TRUST_LAST_IP_NO => $helper->__('No'),
|
124 |
+
self::TWO_FACTOR_AUTH_TRUST_LAST_IP_YES => $helper->__('Yes')
|
125 |
+
);
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
*
|
130 |
+
*/
|
131 |
+
public function provideCurrentCode()
|
132 |
+
{
|
133 |
+
if ($this->isCodeByEmailEnabled()) {
|
134 |
+
$this->sendCodeByEmail();
|
135 |
+
}
|
136 |
+
|
137 |
+
//no other methods implemented
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* @return bool
|
142 |
+
*/
|
143 |
+
public function isCodeByEmailEnabled()
|
144 |
+
{
|
145 |
+
return $this->getMethod() == self::TWO_FACTOR_AUTH_METHOD_EMAIL;
|
146 |
+
}
|
147 |
+
|
148 |
+
/**
|
149 |
+
* @return mixed
|
150 |
+
*/
|
151 |
+
public function sendCodeByEmail()
|
152 |
+
{
|
153 |
+
$email = $this->getUser()->getEmail();
|
154 |
+
$templateId = self::TWO_FACTOR_AUTH_CODE_EMAIL_TEMPLATE;
|
155 |
+
$identity = self::TWO_FACTOR_AUTH_CODE_EMAIL_IDENTITY;
|
156 |
+
|
157 |
+
$discrepancyOptions = $this->getDiscrepancyOptions();
|
158 |
+
$discrepancyLabel = isset($discrepancyOptions[$this->getDiscrepancy()]) ? $discrepancyOptions[$this->getDiscrepancy()] : '';
|
159 |
+
|
160 |
+
$emailVariables = array(
|
161 |
+
'auth_code' => $this->getCurrentCode(),
|
162 |
+
'discrepancy_label' => $discrepancyLabel,
|
163 |
+
);
|
164 |
+
|
165 |
+
/* @var $emailTemplate Mage_Core_Model_Email_Template */
|
166 |
+
$emailTemplate = Mage::getModel('core/email_template');
|
167 |
+
$emailTemplate->sendTransactional($templateId, $identity, $email, null, $emailVariables);
|
168 |
+
|
169 |
+
$sentSuccess = $emailTemplate->getSentSuccess();
|
170 |
+
|
171 |
+
return $sentSuccess;
|
172 |
+
}
|
173 |
+
|
174 |
+
/**
|
175 |
+
* @return string
|
176 |
+
*/
|
177 |
+
protected function getTitleForQRCode()
|
178 |
+
{
|
179 |
+
$name = Mage::getStoreConfig('general/store_information/name');
|
180 |
+
|
181 |
+
return $name;
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* @return string|null
|
186 |
+
*/
|
187 |
+
protected function getNameForQRCode()
|
188 |
+
{
|
189 |
+
$user = $this->getUser();
|
190 |
+
|
191 |
+
return $user->getUsername();
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* @return Nortoneo_TwoFactorAuth_Model_Lib_GoogleAuthenticator
|
196 |
+
*/
|
197 |
+
protected function getAuthenticator()
|
198 |
+
{
|
199 |
+
if ($this->authenticator === null) {
|
200 |
+
$this->authenticator = Mage::getModel('nortoneo_twofactorauth/lib_googleAuthenticator');
|
201 |
+
}
|
202 |
+
|
203 |
+
return $this->authenticator;
|
204 |
+
}
|
205 |
+
|
206 |
+
/**
|
207 |
+
* @return Mage_Admin_Model_User
|
208 |
+
*/
|
209 |
+
protected function getUser()
|
210 |
+
{
|
211 |
+
$userId = $this->getUserId();
|
212 |
+
$user = Mage::getModel('admin/user')->load($userId);
|
213 |
+
|
214 |
+
return $user;
|
215 |
+
}
|
216 |
+
}
|
app/code/community/Nortoneo/TwoFactorAuth/controllers/Adminhtml/LoginController.php
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Nortoneo_TwoFactorAuth
|
4 |
+
* @author Lukasz Szczedzina <contact@nortoneo.com>
|
5 |
+
* @website http://nortoneo.com
|
6 |
+
*/
|
7 |
+
class Nortoneo_TwoFactorAuth_Adminhtml_LoginController extends Mage_Adminhtml_Controller_Action
|
8 |
+
{
|
9 |
+
public function indexAction()
|
10 |
+
{
|
11 |
+
if ($code = $this->getRequest()->getPost('code')) {
|
12 |
+
$this->processCode($code);
|
13 |
+
|
14 |
+
return;
|
15 |
+
}
|
16 |
+
|
17 |
+
$this->loadLayout();
|
18 |
+
$this->renderLayout();
|
19 |
+
}
|
20 |
+
|
21 |
+
public function resendAction()
|
22 |
+
{
|
23 |
+
/** @var Nortoneo_TwoFactorAuth_Model_UserSettings $authSettings */
|
24 |
+
$authSettings = Mage::helper('nortoneo_twofactorauth')->getCurrentUserSettingsModel();
|
25 |
+
$authSettings->provideCurrentCode();
|
26 |
+
|
27 |
+
$this->_redirect('nortoneo_twofactorauth/login/index');
|
28 |
+
}
|
29 |
+
|
30 |
+
protected function processCode($code)
|
31 |
+
{
|
32 |
+
$code = str_replace(' ', '', $code);
|
33 |
+
/** @var Nortoneo_TwoFactorAuth_Model_UserSettings $authSettings */
|
34 |
+
$authSettings = Mage::helper('nortoneo_twofactorauth')->getCurrentUserSettingsModel();
|
35 |
+
$isCodeValid = $authSettings->verifyCode($code);
|
36 |
+
if ($isCodeValid) {
|
37 |
+
Mage::helper('nortoneo_twofactorauth')->setCurrentUserValidated(true);
|
38 |
+
$currentIp = Mage::helper('core/http')->getRemoteAddr();
|
39 |
+
$authSettings->setLastIp($currentIp);
|
40 |
+
$authSettings->save();
|
41 |
+
$this->_redirect('adminhtml');
|
42 |
+
return;
|
43 |
+
}
|
44 |
+
|
45 |
+
Mage::getSingleton('admin/session')->unsetAll();
|
46 |
+
$this->_redirect('adminhtml/index/logout');
|
47 |
+
}
|
48 |
+
|
49 |
+
protected function _isAllowed()
|
50 |
+
{
|
51 |
+
return true;
|
52 |
+
}
|
53 |
+
|
54 |
+
}
|
app/code/community/Nortoneo/TwoFactorAuth/controllers/Adminhtml/UserSettingsController.php
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Nortoneo_TwoFactorAuth
|
4 |
+
* @author Lukasz Szczedzina <contact@nortoneo.com>
|
5 |
+
* @website http://nortoneo.com
|
6 |
+
*/
|
7 |
+
class Nortoneo_TwoFactorAuth_Adminhtml_UserSettingsController extends Mage_Adminhtml_Controller_Action
|
8 |
+
{
|
9 |
+
public function indexAction()
|
10 |
+
{
|
11 |
+
$this->loadLayout();
|
12 |
+
$this->_addContent($this->getLayout()->createBlock('nortoneo_twofactorauth/adminhtml_userSettings_edit'))
|
13 |
+
->_addLeft($this->getLayout()->createBlock('nortoneo_twofactorauth/adminhtml_userSettings_edit_tabs'));
|
14 |
+
$this->renderLayout();
|
15 |
+
}
|
16 |
+
|
17 |
+
public function validateAction()
|
18 |
+
{
|
19 |
+
$this->loadLayout();
|
20 |
+
$this->_addContent($this->getLayout()->createBlock('nortoneo_twofactorauth/adminhtml_userSettings_validate'))
|
21 |
+
->_addLeft($this->getLayout()->createBlock('nortoneo_twofactorauth/adminhtml_userSettings_validate_tabs'));
|
22 |
+
$this->renderLayout();
|
23 |
+
}
|
24 |
+
|
25 |
+
public function validatePostAction()
|
26 |
+
{
|
27 |
+
if ($code = $this->getRequest()->getPost('code')) {
|
28 |
+
$code = str_replace(' ', '', $code);
|
29 |
+
try {
|
30 |
+
$model = Mage::helper('nortoneo_twofactorauth')->getCurrentUserSettingsModel();
|
31 |
+
if (!$model->verifyCode($code)) {
|
32 |
+
$model->setData('is_active', 0);
|
33 |
+
$this->_getSession()->addError(Mage::helper('nortoneo_twofactorauth')->__('Code not validated. Protection disabled.'));
|
34 |
+
} else {
|
35 |
+
$this->_getSession()->addSuccess(Mage::helper('nortoneo_twofactorauth')->__('Code validated. Protection enabled.'));
|
36 |
+
$model->setData('is_active', 1);
|
37 |
+
Mage::helper('nortoneo_twofactorauth')->setCurrentUserValidated(true);
|
38 |
+
}
|
39 |
+
$model->save();
|
40 |
+
} catch (Mage_Core_Exception $e) {
|
41 |
+
$this->_getSession()->addError($e->getMessage());
|
42 |
+
} catch (Exception $e) {
|
43 |
+
$this->_getSession()->addError(Mage::helper('nortoneo_twofactorauth')->__('Unable to save settings.'));
|
44 |
+
Mage::logException($e);
|
45 |
+
}
|
46 |
+
}
|
47 |
+
|
48 |
+
$this->_redirect('*/*/index');
|
49 |
+
}
|
50 |
+
|
51 |
+
public function regenerateSecretAction()
|
52 |
+
{
|
53 |
+
$userSettingsModel = Mage::helper('nortoneo_twofactorauth')->getCurrentUserSettingsModel();
|
54 |
+
$userSettingsModel->setData('is_active', 0);
|
55 |
+
$userSettingsModel->setSecret($userSettingsModel->generateSecret());
|
56 |
+
$userSettingsModel->save();
|
57 |
+
|
58 |
+
$this->_redirect('*/*/index');
|
59 |
+
}
|
60 |
+
|
61 |
+
public function saveAction()
|
62 |
+
{
|
63 |
+
$requireValidation = false;
|
64 |
+
if ($data = $this->getRequest()->getPost()) {
|
65 |
+
try {
|
66 |
+
$model = Mage::helper('nortoneo_twofactorauth')->getCurrentUserSettingsModel();
|
67 |
+
if ($data['is_active'] && (!$model->getIsActive() || $model->getMethod() != $data['method'])) {
|
68 |
+
$requireValidation = true;
|
69 |
+
$model->setData('is_active', 0);
|
70 |
+
} else {
|
71 |
+
$model->setData('is_active', $data['is_active']);
|
72 |
+
}
|
73 |
+
$model->setData('trust_last_ip', $data['trust_last_ip']);
|
74 |
+
$model->setData('method', $data['method']);
|
75 |
+
$model->setData('discrepancy', $data['discrepancy']);
|
76 |
+
$model->save();
|
77 |
+
|
78 |
+
if ($requireValidation) {
|
79 |
+
$model->provideCurrentCode();
|
80 |
+
}
|
81 |
+
|
82 |
+
$this->_getSession()->addSuccess(
|
83 |
+
Mage::helper('nortoneo_twofactorauth')->__('Settings has been saved.')
|
84 |
+
);
|
85 |
+
} catch (Mage_Core_Exception $e) {
|
86 |
+
$this->_getSession()->addError($e->getMessage());
|
87 |
+
} catch (Exception $e) {
|
88 |
+
$this->_getSession()->addError(Mage::helper('nortoneo_twofactorauth')->__('Unable to save settings.'));
|
89 |
+
Mage::logException($e);
|
90 |
+
}
|
91 |
+
}
|
92 |
+
if ($requireValidation) {
|
93 |
+
$this->_redirect('*/*/validate');
|
94 |
+
} else {
|
95 |
+
$this->_redirect('*/*/index');
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
protected function _isAllowed()
|
100 |
+
{
|
101 |
+
return Mage::getSingleton('admin/session')->isAllowed('system/nortoneo_twofactor_auth');
|
102 |
+
}
|
103 |
+
|
104 |
+
}
|
app/code/community/Nortoneo/TwoFactorAuth/etc/adminhtml.xml
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
|
3 |
+
<config>
|
4 |
+
<menu>
|
5 |
+
<system>
|
6 |
+
<children>
|
7 |
+
<nortoneo_twofactor_auth translate="title">
|
8 |
+
<title>Two Factor Authentication</title>
|
9 |
+
<action>nortoneo_twofactorauth/userSettings</action>
|
10 |
+
<sort_order>100</sort_order>
|
11 |
+
</nortoneo_twofactor_auth>
|
12 |
+
</children>
|
13 |
+
</system>
|
14 |
+
</menu>
|
15 |
+
<acl>
|
16 |
+
<resources>
|
17 |
+
<admin>
|
18 |
+
<children>
|
19 |
+
<system>
|
20 |
+
<children>
|
21 |
+
<nortoneo_twofactor_auth translate="title">
|
22 |
+
<title>Two Factor Authentication</title>
|
23 |
+
</nortoneo_twofactor_auth>
|
24 |
+
</children>
|
25 |
+
</system>
|
26 |
+
</children>
|
27 |
+
</admin>
|
28 |
+
</resources>
|
29 |
+
</acl>
|
30 |
+
</config>
|
app/code/community/Nortoneo/TwoFactorAuth/etc/config.xml
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<Nortoneo_TwoFactorAuth>
|
5 |
+
<version>0.1.0</version>
|
6 |
+
</Nortoneo_TwoFactorAuth>
|
7 |
+
</modules>
|
8 |
+
<global>
|
9 |
+
<models>
|
10 |
+
<nortoneo_twofactorauth>
|
11 |
+
<class>Nortoneo_TwoFactorAuth_Model</class>
|
12 |
+
<resourceModel>nortoneo_twofactorauth_resource</resourceModel>
|
13 |
+
</nortoneo_twofactorauth>
|
14 |
+
<nortoneo_twofactorauth_resource>
|
15 |
+
<class>Nortoneo_TwoFactorAuth_Model_Resource</class>
|
16 |
+
<entities>
|
17 |
+
<userSettings>
|
18 |
+
<table>nortoneo_twofactorauth_user_settings</table>
|
19 |
+
</userSettings>
|
20 |
+
</entities>
|
21 |
+
</nortoneo_twofactorauth_resource>
|
22 |
+
</models>
|
23 |
+
<blocks>
|
24 |
+
<nortoneo_twofactorauth>
|
25 |
+
<class>Nortoneo_TwoFactorAuth_Block</class>
|
26 |
+
</nortoneo_twofactorauth>
|
27 |
+
</blocks>
|
28 |
+
<helpers>
|
29 |
+
<nortoneo_twofactorauth>
|
30 |
+
<class>Nortoneo_TwoFactorAuth_Helper</class>
|
31 |
+
</nortoneo_twofactorauth>
|
32 |
+
</helpers>
|
33 |
+
<resources>
|
34 |
+
<nortoneo_twofactorauth_setup>
|
35 |
+
<setup>
|
36 |
+
<module>Nortoneo_TwoFactorAuth</module>
|
37 |
+
</setup>
|
38 |
+
</nortoneo_twofactorauth_setup>
|
39 |
+
</resources>
|
40 |
+
<template>
|
41 |
+
<email>
|
42 |
+
<nortoneo_twofactorauth_code translate="label" module="adminhtml">
|
43 |
+
<label>Two Factor Authentication Code</label>
|
44 |
+
<file>nortoneo/twofactorauth/code.html</file>
|
45 |
+
<type>html</type>
|
46 |
+
</nortoneo_twofactorauth_code>
|
47 |
+
</email>
|
48 |
+
</template>
|
49 |
+
</global>
|
50 |
+
<admin>
|
51 |
+
<routers>
|
52 |
+
<nortoneo_twofactorauth>
|
53 |
+
<use>admin</use>
|
54 |
+
<args>
|
55 |
+
<frontName>nortoneo_twofactorauth</frontName>
|
56 |
+
<module>Nortoneo_TwoFactorAuth_Adminhtml</module>
|
57 |
+
</args>
|
58 |
+
</nortoneo_twofactorauth>
|
59 |
+
</routers>
|
60 |
+
</admin>
|
61 |
+
<adminhtml>
|
62 |
+
<layout>
|
63 |
+
<updates>
|
64 |
+
<nortoneo_twofactorauth>
|
65 |
+
<file>nortoneo/twofactorauth.xml</file>
|
66 |
+
</nortoneo_twofactorauth>
|
67 |
+
</updates>
|
68 |
+
</layout>
|
69 |
+
<translate>
|
70 |
+
<modules>
|
71 |
+
<nortoneo_twofactorauth>
|
72 |
+
<files>
|
73 |
+
<default>nortoneo/twofactorauth.csv</default>
|
74 |
+
</files>
|
75 |
+
</nortoneo_twofactorauth>
|
76 |
+
</modules>
|
77 |
+
</translate>
|
78 |
+
<events>
|
79 |
+
<controller_action_predispatch>
|
80 |
+
<observers>
|
81 |
+
<nortoneo_twofactorauth_authentication>
|
82 |
+
<type>singleton</type>
|
83 |
+
<class>nortoneo_twofactorauth/observer</class>
|
84 |
+
<method>processAuthentication</method>
|
85 |
+
</nortoneo_twofactorauth_authentication>
|
86 |
+
</observers>
|
87 |
+
</controller_action_predispatch>
|
88 |
+
</events>
|
89 |
+
</adminhtml>
|
90 |
+
</config>
|
app/code/community/Nortoneo/TwoFactorAuth/sql/nortoneo_twofactorauth_setup/install-0.1.0.php
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Nortoneo_TwoFactorAuth
|
4 |
+
* @author Lukasz Szczedzina <contact@nortoneo.com>
|
5 |
+
* @website http://nortoneo.com
|
6 |
+
*/
|
7 |
+
/* @var $installer Mage_Core_Model_Resource_Setup */
|
8 |
+
$installer = $this;
|
9 |
+
|
10 |
+
$connection = $installer->getConnection();
|
11 |
+
$tableName = $installer->getTable('nortoneo_twofactorauth/userSettings');
|
12 |
+
$isTableExists = $connection->isTableExists($tableName);
|
13 |
+
if (!$isTableExists) {
|
14 |
+
$table = $connection
|
15 |
+
->newTable($tableName)
|
16 |
+
->addColumn('settings_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
|
17 |
+
'identity' => true,
|
18 |
+
'unsigned' => true,
|
19 |
+
'nullable' => false,
|
20 |
+
'primary' => true,
|
21 |
+
), 'SETTINGS ID')
|
22 |
+
->addColumn('user_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
|
23 |
+
'unsigned' => true,
|
24 |
+
'nullable' => false,
|
25 |
+
), 'USER ID')
|
26 |
+
->addColumn('is_active', Varien_Db_Ddl_Table::TYPE_TINYINT, null, array(
|
27 |
+
'unsigned' => true,
|
28 |
+
'nullable' => false,
|
29 |
+
), 'IS ACTIVE')
|
30 |
+
->addColumn('method', Varien_Db_Ddl_Table::TYPE_TINYINT, null, array(
|
31 |
+
'unsigned' => true,
|
32 |
+
'nullable' => false,
|
33 |
+
), 'METHOD')
|
34 |
+
->addColumn('trust_last_ip', Varien_Db_Ddl_Table::TYPE_TINYINT, null, array(
|
35 |
+
'unsigned' => true,
|
36 |
+
'nullable' => false,
|
37 |
+
), 'TRUST LAST IP')
|
38 |
+
->addColumn('last_ip', Varien_Db_Ddl_Table::TYPE_VARCHAR, 15, array(
|
39 |
+
'nullable' => true,
|
40 |
+
), 'LAST IP')
|
41 |
+
->addColumn('discrepancy', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
|
42 |
+
'unsigned' => true,
|
43 |
+
'nullable' => false,
|
44 |
+
), 'DISCREPANCY')
|
45 |
+
->addColumn('secret', Varien_Db_Ddl_Table::TYPE_VARCHAR, 255, array(
|
46 |
+
'nullable' => false,
|
47 |
+
), 'SECRET')
|
48 |
+
->addForeignKey($installer->getFkName('nortoneo_twofactorauth/userSettings', 'user_id', 'admin/user', 'user_id'),
|
49 |
+
'user_id', $installer->getTable('admin/user'), 'user_id',
|
50 |
+
Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
|
51 |
+
->addIndex(
|
52 |
+
$this->getIdxName($tableName, 'user_id', Varien_Db_Adapter_Interface::INDEX_TYPE_UNIQUE),
|
53 |
+
'user_id',
|
54 |
+
array('type' => Varien_Db_Adapter_Interface::INDEX_TYPE_UNIQUE)
|
55 |
+
);
|
56 |
+
|
57 |
+
$connection->createTable($table);
|
58 |
+
}
|
app/design/adminhtml/default/default/layout/nortoneo/twofactorauth.xml
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
|
3 |
+
<layout>
|
4 |
+
<nortoneo_twofactorauth_login_index>
|
5 |
+
<block type="core/text_list" name="root" output="toHtml">
|
6 |
+
<block type="adminhtml/template" name="two_factor_authenticate_form"
|
7 |
+
template="nortoneo/twofactorauth/login.phtml"/>
|
8 |
+
</block>
|
9 |
+
</nortoneo_twofactorauth_login_index>
|
10 |
+
</layout>
|
app/design/adminhtml/default/default/template/nortoneo/twofactorauth/login.phtml
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
2 |
+
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
|
3 |
+
<head>
|
4 |
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
5 |
+
<title><?php echo Mage::helper('adminhtml')->__('Log into Magento Admin Page') ?></title>
|
6 |
+
<link type="text/css" rel="stylesheet" href="<?php echo $this->getSkinUrl('reset.css') ?>" media="all" />
|
7 |
+
<link type="text/css" rel="stylesheet" href="<?php echo $this->getSkinUrl('boxes.css') ?>" media="all" />
|
8 |
+
<link rel="icon" href="<?php echo $this->getSkinUrl('favicon.ico') ?>" type="image/x-icon" />
|
9 |
+
<link rel="shortcut icon" href="<?php echo $this->getSkinUrl('favicon.ico') ?>" type="image/x-icon" />
|
10 |
+
|
11 |
+
<script type="text/javascript" src="<?php echo $this->getJsUrl('prototype/prototype.js') ?>"></script>
|
12 |
+
<script type="text/javascript" src="<?php echo $this->getJsUrl('prototype/validation.js') ?>"></script>
|
13 |
+
<script type="text/javascript" src="<?php echo $this->getJsUrl('scriptaculous/effects.js') ?>"></script>
|
14 |
+
<script type="text/javascript" src="<?php echo $this->getJsUrl('mage/adminhtml/form.js') ?>"></script>
|
15 |
+
<script type="text/javascript" src="<?php echo $this->getJsUrl('mage/captcha.js') ?>"></script>
|
16 |
+
|
17 |
+
<!--[if IE]> <link rel="stylesheet" href="<?php echo $this->getSkinUrl('iestyles.css') ?>" type="text/css" media="all" /> <![endif]-->
|
18 |
+
<!--[if lt IE 7]> <link rel="stylesheet" href="<?php echo $this->getSkinUrl('below_ie7.css') ?>" type="text/css" media="all" /> <![endif]-->
|
19 |
+
<!--[if IE 7]> <link rel="stylesheet" href="<?php echo $this->getSkinUrl('ie7.css') ?>" type="text/css" media="all" /> <![endif]-->
|
20 |
+
</head>
|
21 |
+
<body id="page-login" onload="document.forms.loginForm.code.focus();">
|
22 |
+
<div class="login-container">
|
23 |
+
<div class="login-box">
|
24 |
+
<form method="post" action="" id="loginForm" autocomplete="off">
|
25 |
+
<div class="login-form">
|
26 |
+
<input name="form_key" type="hidden" value="<?php echo $this->getFormKey() ?>" />
|
27 |
+
<h2><?php echo Mage::helper('nortoneo_twofactorauth')->__('Two Factor Authentication') ?></h2>
|
28 |
+
<div id="messages">
|
29 |
+
<?php echo $this->getMessagesBlock()->toHtml() ?>
|
30 |
+
</div>
|
31 |
+
<div class="input-box input-left"><label for="code"><?php echo Mage::helper('nortoneo_twofactorauth')->__('Authentication Code:') ?></label><br/>
|
32 |
+
<input type="text" id="code" name="code" value="" class="required-entry input-text" /></div>
|
33 |
+
<div class="clear"></div>
|
34 |
+
<div class="form-buttons">
|
35 |
+
<?php if(Mage::helper('nortoneo_twofactorauth')->getCurrentUserSettingsModel()->isCodeByEmailEnabled()): ?>
|
36 |
+
<a class="left" href="<?php echo Mage::helper('adminhtml')->getUrl('nortoneo_twofactorauth/login/resend', array('_nosecret' => true)) ?>"><?php echo Mage::helper('nortoneo_twofactorauth')->__('Resend code') ?></a>
|
37 |
+
<?php endif; ?>
|
38 |
+
<input type="submit" class="form-button" value="<?php echo Mage::helper('core')->quoteEscape(Mage::helper('nortoneo_twofactorauth')->__('Enter Code')) ?>" title="<?php echo Mage::helper('core')->quoteEscape(Mage::helper('nortoneo_twofactorauth')->__('Authentication Code')) ?>" /></div>
|
39 |
+
</div>
|
40 |
+
</form>
|
41 |
+
<div class="bottom"></div>
|
42 |
+
<script type="text/javascript">
|
43 |
+
var loginForm = new varienForm('loginForm');
|
44 |
+
</script>
|
45 |
+
</div>
|
46 |
+
</div>
|
47 |
+
</body>
|
48 |
+
</html>
|
49 |
+
|
app/design/adminhtml/default/default/template/nortoneo/twofactorauth/usersettings.phtml
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$helper = Mage::helper('nortoneo_twofactorauth');
|
3 |
+
/** @var Nortoneo_TwoFactorAuth_Model_UserSettings $settings */
|
4 |
+
$settings = $this->getUserSettingsModel();
|
5 |
+
?>
|
6 |
+
<div class="entry-edit">
|
7 |
+
<?php echo $this->getFormHtml();?>
|
8 |
+
</div>
|
9 |
+
<?php echo $this->getChildHtml('form_after');?>
|
10 |
+
|
11 |
+
<div class="box-left">
|
12 |
+
<div class="entry-edit">
|
13 |
+
<div class="entry-edit-head">
|
14 |
+
<h4 class="icon-head head-account"><?php echo $helper->__('Mobile application setup') ?></h4>
|
15 |
+
</div>
|
16 |
+
<div class="fieldset">
|
17 |
+
<table cellspacing="0" class="form-list">
|
18 |
+
<tr>
|
19 |
+
<td class="label"><label>Your secret key</label></td>
|
20 |
+
<td class="value"><strong><?php echo $settings->getSecret(); ?></strong></td>
|
21 |
+
</tr>
|
22 |
+
<tr>
|
23 |
+
<td class="label"><label><?php echo $helper->__('QR Code for mobile app') ?></label></td>
|
24 |
+
<td class="value"><img src="<?php echo $settings->getQRCodeGoogleUrl(); ?>" /></td>
|
25 |
+
</tr>
|
26 |
+
</table>
|
27 |
+
<p><?php echo $helper->__('Install Google Authenticator app to generate tokens on your smartphone.') ?></p>
|
28 |
+
<p><?php echo $helper->__('Available for') ?>
|
29 |
+
<a href="https://m.google.com/authenticator" target="_blank">Android</a>
|
30 |
+
<a href="https://itunes.apple.com/pl/app/google-authenticator/id388497605" target="_blank">iOS</a>
|
31 |
+
Blackberry
|
32 |
+
</p>
|
33 |
+
</div>
|
34 |
+
</div>
|
35 |
+
</div>
|
app/etc/modules/Nortoneo_TwoFactorAuth.xml
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<Nortoneo_TwoFactorAuth>
|
5 |
+
<active>true</active>
|
6 |
+
<codePool>community</codePool>
|
7 |
+
</Nortoneo_TwoFactorAuth>
|
8 |
+
</modules>
|
9 |
+
</config>
|
app/locale/en_US/nortoneo/twofactorauth.csv
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"Are you sure? If you are using mobile app you will have to rescan QR code. For safety reasons you will have to enable protection again.","Are you sure? If you are using mobile app you will have to rescan QR code. For safety reasons you will have to enable protection again."
|
2 |
+
"Regenerate secret key","Regenerate secret key"
|
3 |
+
"Two Factor Authentication Settings","Two Factor Authentication Settings"
|
4 |
+
"Settings","Settings"
|
5 |
+
"User Settings","User Settings"
|
6 |
+
"Status","Status"
|
7 |
+
"Enabled","Enabled"
|
8 |
+
"Disabled","Disabled"
|
9 |
+
"Trust last IP address","Trust last IP address"
|
10 |
+
"Discrepancy","Discrepancy"
|
11 |
+
"How long your code should be valid.","How long your code should be valid."
|
12 |
+
"Authentication Method","Authentication Method"
|
13 |
+
"Ask for code only if IP has changed since last successful login?","Ask for code only if IP has changed since last successful login?"
|
14 |
+
"Code validation","Code validation"
|
15 |
+
"Two Factor Authentication Validation","Two Factor Authentication Validation"
|
16 |
+
"Authentication Code","Authentication Code"
|
17 |
+
"Code not validated. Protection disabled.","Code not validated. Protection disabled."
|
18 |
+
"Code validated. Protection enabled.","Code validated. Protection enabled."
|
19 |
+
"Unable to save settings.","Unable to save settings."
|
20 |
+
"Settings has been saved.","Settings has been saved."
|
21 |
+
"Send me codes by e-mail (%s)","Send me codes by e-mail (%s)"
|
22 |
+
"I will use mobile application","I will use mobile application"
|
23 |
+
"%s seconds","%s seconds"
|
24 |
+
"No","No"
|
25 |
+
"Yes","Yes"
|
26 |
+
"Two Factor Authentication","Two Factor Authentication"
|
27 |
+
"Authentication Code:","Authentication Code:"
|
28 |
+
"Enter Code","Enter Code"
|
29 |
+
"Resend code","Resend code"
|
30 |
+
"Mobile application setup","Mobile application setup"
|
31 |
+
"QR Code for mobile app","QR Code for mobile app"
|
32 |
+
"Install Google Authenticator app to generate tokens on your smartphone.","Install Google Authenticator app to generate tokens on your smartphone."
|
33 |
+
"Available for","Available for"
|
app/locale/en_US/template/email/nortoneo/twofactorauth/code.html
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
1 |
+
<!--@subject Two Factor Authentication @-->
|
2 |
+
|
3 |
+
<p>Your code is: <strong>{{var auth_code}}</strong></p>
|
4 |
+
<p>This code is valid for {{var discrepancy_label}}</p>
|
app/locale/pl_PL/nortoneo/twofactorauth.csv
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"Are you sure? If you are using mobile app you will have to rescan QR code. For safety reasons you will have to enable protection again.","Jesteś pewien? Jeśli używasz apki mobilnej będziesz musiał ponownie zeskanować kod QR. Dla bezpieczeństwa ochrona zostanie wyłączona. Będziesz musiał włączyć ją ponownie."
|
2 |
+
"Regenerate secret key","Zmień swój klucz prywatny"
|
3 |
+
"Two Factor Authentication Settings","Ustawienia dwuetapowej weryfikacji"
|
4 |
+
"Settings","Ustawienia"
|
5 |
+
"User Settings","Ustawienia użytkownika"
|
6 |
+
"Status","Status"
|
7 |
+
"Enabled","Włączone"
|
8 |
+
"Disabled","Wyłączone"
|
9 |
+
"Trust last IP address","Ufaj ostatniemu adresowi IP"
|
10 |
+
"Discrepancy","Rozbieżność"
|
11 |
+
"How long your code should be valid.","Jak długo powinien być ważny twój kod."
|
12 |
+
"Authentication Method","Metoda weryfikacji"
|
13 |
+
"Ask for code only if IP has changed since last successful login?","Pytać o kod tylko gdy twój adres IP zmienił się od ostatniego poprawnego logowania?"
|
14 |
+
"Code validation","Weryfikacja kodu"
|
15 |
+
"Two Factor Authentication Validation","Walidacja weryfikacji dwuetapowej"
|
16 |
+
"Authentication Code","Kod autoryzacji"
|
17 |
+
"Code not validated. Protection disabled.","Kod niepoprawny. Ochrona wyłączona."
|
18 |
+
"Code validated. Protection enabled.","Kod poprawny. Ochrona włączona."
|
19 |
+
"Unable to save settings.","Nie udało się zapisać ustawień."
|
20 |
+
"Settings has been saved.","Ustawienia zostały zapisane."
|
21 |
+
"Send me codes by e-mail (%s)","Wysyłaj mi kody na e-mail (%s)"
|
22 |
+
"I will use mobile application","Będę używać aplikacji mobilnej"
|
23 |
+
"%s seconds","%s sekund"
|
24 |
+
"No","Nie"
|
25 |
+
"Yes","Tak"
|
26 |
+
"Two Factor Authentication","Weryfikacja dwuetapowa"
|
27 |
+
"Authentication Code:","Kod autoryzacyjny:"
|
28 |
+
"Enter Code","Wprowadź kod"
|
29 |
+
"Resend code","Wyślij kod ponownie"
|
30 |
+
"Mobile application setup","Ustawienia aplikacji mobilnej"
|
31 |
+
"QR Code for mobile app","Kod QR dla aplikacji mobilnej"
|
32 |
+
"Install Google Authenticator app to generate tokens on your smartphone.","Zainstaluj na swojego smartphone`a aplikację Google Authenticator."
|
33 |
+
"Available for","Dostępna dla"
|
package.xml
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<package>
|
3 |
+
<name>Nortoneo_TwoFactorAuth</name>
|
4 |
+
<version>0.1.0</version>
|
5 |
+
<stability>stable</stability>
|
6 |
+
<license uri="BSD">http://www.opensource.org/licenses/bsd-license.php</license>
|
7 |
+
<channel>community</channel>
|
8 |
+
<extends/>
|
9 |
+
<summary>Nortoneo TwoFactorAuth module helps you secure your admin panel from unauthorized access. Admin users will be able to set up two factor authorization.</summary>
|
10 |
+
<description>This module will give admin users possibility to set up Two Factor Authorization.
|
11 |
+
Once enabled - when user will want to login to Magento back-office he will need to provide special code that can be delivered by email or generated by Google Authenticator app on his smartphone.
|
12 |
+
Module include features like:
|
13 |
+
- trust last IP (authorization codes will not be required until IP address has been changed since last successful login)
|
14 |
+
- setting duration of how long codes will be valid
|
15 |
+
- possibility to send authorization codes by email
|
16 |
+
</description>
|
17 |
+
<notes>Nortoneo_TwoFactorAuth v0.1.0</notes>
|
18 |
+
<authors><author><name>Lukasz Szczedzina</name><user>lszczedzina</user><email>contact@nortoneo.com</email></author></authors>
|
19 |
+
<date>2016-11-17</date>
|
20 |
+
<time>10:04:51</time>
|
21 |
+
<contents><target name="magecommunity"><dir name="Nortoneo"><dir name="TwoFactorAuth"><dir name="Block"><dir name="Adminhtml"><dir name="UserSettings"><dir name="Edit"><file name="Form.php" hash="6f496577d5e3c08d3255e09680a46024"/><dir name="Tab"><file name="Form.php" hash="68d4bf0a3dbcfe3b7d3f9642c7302f29"/></dir><file name="Tabs.php" hash="cbae7c9720d0e1563f95f765a9010ad1"/></dir><file name="Edit.php" hash="bb939f512238135a65e88a60160d8ca6"/><dir name="Validate"><file name="Form.php" hash="34fab66cd41d5a5c055b37a6355784cf"/><dir name="Tab"><file name="Form.php" hash="64fe24aa9e214fa491c681e46b144fa3"/></dir><file name="Tabs.php" hash="4cf8bc00930be77d74250963d3be255f"/></dir><file name="Validate.php" hash="ba032a228478d3468242a2b927d6c972"/></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="644f4c382330686b91f63a61ddfb9adb"/></dir><dir name="Model"><dir name="Lib"><file name="GoogleAuthenticator.php" hash="12828be6b50bd8920159e771b294969c"/></dir><file name="Observer.php" hash="2a23af96f0801a699e7f9ee30733a6a6"/><dir name="Resource"><dir name="UserSettings"><file name="Collection.php" hash="3d36a299e953a37e02dec181eb59b2db"/></dir><file name="UserSettings.php" hash="d0564bfa5ffefd69fffb5cc0ec0619e6"/></dir><file name="UserSettings.php" hash="8aa04e0bf992de4e67ed29015d0940fe"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="LoginController.php" hash="01b20f0147be631b94c852c47838c426"/><file name="UserSettingsController.php" hash="e82198dc27f85cfab5a75c9ff67b5e2e"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="531ff30bba43ba97f8b63a393be53d61"/><file name="config.xml" hash="6c762368daff079846c907bc9575144d"/></dir><dir name="sql"><dir name="nortoneo_twofactorauth_setup"><file name="install-0.1.0.php" hash="2774d68ffc719f1f92bdd1dbfef82b9f"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><dir name="nortoneo"><file name="twofactorauth.xml" hash="f58a9b11f09c331778942c21afad1d7c"/></dir></dir><dir name="template"><dir name="nortoneo"><dir><dir name="twofactorauth"><file name="login.phtml" hash="36f70386c04eb13351cd9e35fcb3e313"/><file name="usersettings.phtml" hash="950db47334adcfb3965e9d33e34c2d1b"/></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Nortoneo_TwoFactorAuth.xml" hash="7b66a753a8a4aa8e1ecccb66a42e87dd"/></dir></target><target name="magelocale"><dir name="en_US"><dir name="nortoneo"><file name="twofactorauth.csv" hash="a5dac86614887d217c251dda7bc95d98"/></dir><dir name="template"><dir name="email"><dir name="nortoneo"><dir><dir name="twofactorauth"><file name="code.html" hash="9de7e2f2400073dbb918bccf5228b9ef"/></dir></dir></dir></dir></dir></dir><dir name="pl_PL"><dir name="nortoneo"><file name="twofactorauth.csv" hash="244c3c462fcd63b7f4427a29245773fb"/></dir></dir></target></contents>
|
22 |
+
<compatible/>
|
23 |
+
<dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
|
24 |
+
</package>
|