├── docs
└── EditRole.png
├── app
├── locale
│ └── de_DE
│ │ └── MagentoHackathon_AdvancedAcl.csv
├── etc
│ └── modules
│ │ └── MagentoHackathon_AdvancedAcl.xml
└── code
│ └── community
│ └── MagentoHackathon
│ └── AdvancedAcl
│ ├── Model
│ └── Observer
│ │ ├── Access.php
│ │ ├── Customer.php
│ │ ├── Abstract.php
│ │ ├── Url.php
│ │ ├── Config.php
│ │ ├── Catalog.php
│ │ ├── Sales.php
│ │ └── Role.php
│ ├── Test
│ ├── Config
│ │ ├── ObserverUrlConfigTests.php
│ │ └── ObserverRoleConfigTests.php
│ └── Helper
│ │ └── DataTests.php
│ ├── sql
│ └── magentohackathon_advancedacl_setup
│ │ └── install-1.0.0.php
│ ├── Block
│ └── Adminhtml
│ │ ├── System
│ │ └── Config
│ │ │ └── Switcher.php
│ │ ├── Store
│ │ └── Switcher.php
│ │ └── Permissions
│ │ └── Tab
│ │ └── Stores.php
│ ├── Helper
│ └── Data.php
│ └── etc
│ └── config.xml
├── modman
├── .travis.yml
├── composer.json
└── README.md
/docs/EditRole.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magento-hackathon/AdvancedAcl/HEAD/docs/EditRole.png
--------------------------------------------------------------------------------
/app/locale/de_DE/MagentoHackathon_AdvancedAcl.csv:
--------------------------------------------------------------------------------
1 | "Advanced ACL","Erweiterte Zugriffsbeschränkung"
2 | "Restrict store view access","StoreView-Zugriff einschränken"
3 |
--------------------------------------------------------------------------------
/modman:
--------------------------------------------------------------------------------
1 | app/etc/modules/MagentoHackathon_AdvancedAcl.xml app/etc/modules/MagentoHackathon_AdvancedAcl.xml
2 | app/code/community/MagentoHackathon/AdvancedAcl app/code/community/MagentoHackathon/AdvancedAcl
3 | app/locale/de_DE/MagentoHackathon_AdvancedAcl.csv app/locale/de_DE/MagentoHackathon_AdvancedAcl.csv
4 |
--------------------------------------------------------------------------------
/app/etc/modules/MagentoHackathon_AdvancedAcl.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | true
6 | community
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | php:
3 | - 5.4
4 | - 5.5
5 | env:
6 | matrix:
7 | - MAGENTO_VERSION=magento-ce-1.9.1.0
8 | - MAGENTO_VERSION=magento-ce-1.9.0.1
9 | - MAGENTO_VERSION=magento-ce-1.8.1.0
10 | - MAGENTO_VERSION=magento-ce-1.8.0.0
11 | before_script:
12 | - curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar
13 | - phpenv rehash
14 | - git clone https://github.com/AOEpeople/magento-coding-standard $(pear config-get php_dir)/PHP/CodeSniffer/Standards/Ecg
15 | script:
16 | # Code Style
17 | - php phpcs.phar --config-set ignore_warnings_on_exit --standard=$(pear config-get php_dir)/PHP/CodeSniffer/Standards/Ecg --encoding=utf-8 --report-width=180 ./app
18 | # Unit Tests
19 | - curl -sSL https://raw.githubusercontent.com/AOEpeople/MageTestStand/master/setup.sh | bash
20 | notifications:
21 | email: false
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "magento-hackathon/advanced-acl",
3 | "type": "magento-module",
4 | "license": "OSL-3.0",
5 | "homepage": "https://github.com/magento-hackathon/AdvancedAcl.git",
6 | "description": "Restrict Magento admin permissions to specific websites or storeviews",
7 | "authors": [
8 | {
9 | "name": "Thomas Birke",
10 | "email": "tbirke@netextreme.de"
11 | },
12 | {
13 | "name": "Michael Lühr",
14 | "email": "ml@luehr-software.de"
15 | },
16 | {
17 | "name": "Andre Flitsch",
18 | "email": "andre@pixelperfect.at"
19 | },
20 | {
21 | "name": "Andreas Penz",
22 | "email": "testa.peta@gmail.com"
23 | }
24 | ],
25 | "require":{
26 | "magento-hackathon/magento-composer-installer":"*"
27 | }
28 | }
--------------------------------------------------------------------------------
/app/code/community/MagentoHackathon/AdvancedAcl/Model/Observer/Access.php:
--------------------------------------------------------------------------------
1 | getControllerAction();
18 |
19 | $storeId = $controller->getRequest()->getParam('store');
20 |
21 | if (!$this->getHelper()->hasStoreViewAccess($storeId)) {
22 | $this->deniedAction($controller, self::CATALOG_PRODUCT_INDEX_ROUTE_PATH);
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/code/community/MagentoHackathon/AdvancedAcl/Test/Config/ObserverUrlConfigTests.php:
--------------------------------------------------------------------------------
1 | assertEventObserverDefined(
15 | 'adminhtml',
16 | 'controller_action_predispatch_adminhtml_catalog_product_edit',
17 | 'magentohackathon_advancedacl/observer_url',
18 | 'catalogProductEdit'
19 | );
20 |
21 | $this->assertEventObserverDefined(
22 | 'adminhtml',
23 | 'controller_action_predispatch_adminhtml_catalog_category_edit',
24 | 'magentohackathon_advancedacl/observer_url',
25 | 'catalogCategoryEdit'
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/code/community/MagentoHackathon/AdvancedAcl/Model/Observer/Customer.php:
--------------------------------------------------------------------------------
1 | getCollection();
14 | if ($collection instanceof Mage_Customer_Model_Resource_Customer_Collection) {
15 | $storeIds = $this->getStoreIds();
16 |
17 | if ( ! empty($storeIds)) {
18 | $collection->addAttributeToFilter('store_id', array('in' => $storeIds));
19 | }
20 | }
21 | }
22 |
23 | /**
24 | * retrieves allowed store ids
25 | *
26 | * @return mixed
27 | */
28 | protected function getStoreIds()
29 | {
30 | return Mage::helper('magentohackathon_advancedacl/data')->getActiveRole()->getStoreIds();
31 | }
32 |
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/app/code/community/MagentoHackathon/AdvancedAcl/Model/Observer/Abstract.php:
--------------------------------------------------------------------------------
1 | deniedAction();
26 | return $controller->setFlag('', Mage_Adminhtml_System_ConfigController::FLAG_NO_DISPATCH, true);
27 | return false;
28 | }
29 |
30 | /**
31 | * @param Mage_Core_Controller_Varien_Action $controller
32 | * @param $routePath
33 | */
34 | public function deniedAction($controller, $routePath)
35 | {
36 | /** @var Mage_Core_Model_Url $urlModel */
37 | $urlModel = Mage::helper('adminhtml');
38 | $controller->getResponse()->setRedirect($urlModel->getUrl($routePath));
39 | return;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/code/community/MagentoHackathon/AdvancedAcl/Test/Config/ObserverRoleConfigTests.php:
--------------------------------------------------------------------------------
1 | assertEventObserverDefined(
15 | 'adminhtml',
16 | 'admin_permissions_role_prepare_save',
17 | 'magentohackathon_advancedacl/observer_role',
18 | 'addStoresToRoleModel'
19 | );
20 |
21 | $this->assertEventObserverDefined(
22 | 'adminhtml',
23 | 'admin_roles_save_after',
24 | 'magentohackathon_advancedacl/observer_role',
25 | 'saveAfter'
26 | );
27 |
28 | $this->assertEventObserverDefined(
29 | 'adminhtml',
30 | 'admin_roles_load_after',
31 | 'magentohackathon_advancedacl/observer_role',
32 | 'afterLoad'
33 | );
34 |
35 | $this->assertEventObserverDefined(
36 | 'adminhtml',
37 | 'admin_roles_delete_before',
38 | 'magentohackathon_advancedacl/observer_role',
39 | 'beforeDelete'
40 | );
41 | }
42 | }
--------------------------------------------------------------------------------
/app/code/community/MagentoHackathon/AdvancedAcl/sql/magentohackathon_advancedacl_setup/install-1.0.0.php:
--------------------------------------------------------------------------------
1 | startSetup();
7 |
8 | $table = $installer->getConnection()
9 | ->newTable($installer->getTable('magentohackathon_advancedacl/role_store'))
10 | ->addColumn('role_id', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(
11 | 'nullable' => false,
12 | 'primary' => true,
13 | ), 'Role ID')
14 | ->addColumn('store_id', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(
15 | 'unsigned' => true,
16 | 'nullable' => false,
17 | 'primary' => true,
18 | ), 'Store ID')
19 | ->addIndex($installer->getIdxName('magentohackathon_advancedacl/role_store', array('store_id')),
20 | array('store_id'))
21 | ->addForeignKey($installer->getFkName('magentohackathon_advancedacl/role_store', 'role_id', 'admin/role', 'role_id'),
22 | 'role_id', $installer->getTable('admin/role'), 'role_id',
23 | Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
24 | ->addForeignKey($installer->getFkName('magentohackathon_advancedacl/role_store', 'store_id', 'core/store', 'store_id'),
25 | 'store_id', $installer->getTable('core/store'), 'store_id',
26 | Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
27 | ->setComment('Admin Role To Store Linkage Table');
28 | $installer->getConnection()->createTable($table);
29 |
30 | $installer->endSetup();
--------------------------------------------------------------------------------
/app/code/community/MagentoHackathon/AdvancedAcl/Model/Observer/Url.php:
--------------------------------------------------------------------------------
1 | getRequest()->getParam(self::STORE_PARAM_KEY);
24 | $defaultStoreId = $this->getHelper()->getDefaultStoreId();
25 | $allowedStoreIds = $this->getHelper()->getAllowedStoreIds();
26 |
27 | if (is_null($storeId) && !empty($allowedStoreIds) && !in_array($defaultStoreId, $allowedStoreIds)) {
28 | $storeId = current($allowedStoreIds);
29 | $controller->getRequest()->setParam(self::STORE_PARAM_KEY, $storeId);
30 | }
31 | }
32 |
33 | /**
34 | * @param Varien_Event_Observer $observer
35 | */
36 | public function catalogProductEdit(Varien_Event_Observer $observer)
37 | {
38 | $this->_appendFirstStoreId($observer->getControllerAction());
39 | }
40 |
41 | /**
42 | * @param Varien_Event_Observer $observer
43 | */
44 | public function catalogCategoryEdit(Varien_Event_Observer $observer)
45 | {
46 | $this->_appendFirstStoreId($observer->getControllerAction());
47 | }
48 |
49 | /**
50 | * @param Varien_Event_Observer $observer
51 | */
52 | public function cmsPageIndex(Varien_Event_Observer $observer)
53 | {
54 | $this->_appendFirstStoreId($observer->getControllerAction());
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/app/code/community/MagentoHackathon/AdvancedAcl/Block/Adminhtml/System/Config/Switcher.php:
--------------------------------------------------------------------------------
1 | hasFullAccess()) {
44 | unset($options['default']);
45 | foreach ($options as $key=>$option) {
46 | if (preg_match('/^website_(.+)$/', $key, $matches)) {
47 | if (false === $helper->hasFullWebsiteAccess($matches[1])) {
48 | unset($options[$key]);
49 | }
50 | } elseif (preg_match('/^group_(.+)_(open|close)$/', $key, $matches)) {
51 | if (false === $helper->hasFullStoreGroupAccess($matches[1])) {
52 | unset($options[$key]);
53 | }
54 | } elseif (preg_match('/^store_(.+)$/', $key, $matches)) {
55 | if (false === $helper->hasStoreViewAccess($matches[1])) {
56 | unset($options[$key]);
57 | }
58 | }
59 | }
60 | }
61 |
62 | return $options;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/code/community/MagentoHackathon/AdvancedAcl/Model/Observer/Config.php:
--------------------------------------------------------------------------------
1 |
33 | */
34 |
35 |
36 | /**
37 | * Class MagentoHackathon_AdvancedAcl_Model_Observer_Config
38 | */
39 | class MagentoHackathon_AdvancedAcl_Model_Observer_Config
40 | extends MagentoHackathon_AdvancedAcl_Model_Observer_Abstract
41 | {
42 | public function beforeLoad($observer)
43 | {
44 | $controller = $observer->getControllerAction();
45 | if ($controller instanceof Mage_Adminhtml_System_ConfigController) {
46 | switch ($controller->getRequest()->getActionName()) {
47 | case 'edit':
48 | case 'save':
49 | return $this->_checkScopeAccess($controller);
50 | }
51 | }
52 | }
53 |
54 | protected function _checkScopeAccess($controller)
55 | {
56 | $website = $controller->getRequest()->getParam('website');
57 | $store = $controller->getRequest()->getParam('store');
58 |
59 | if ($this->getHelper()->hasFullAccess() || $this->getHelper()->isSingleStoreMode()) {
60 | // there is no restriction for this user
61 | return;
62 | }
63 |
64 | if ($store) {
65 | if (false === $this->getHelper()->hasStoreViewAccess($store)) {
66 | return $this->denyAccess($controller);
67 | }
68 | } elseif ($website) {
69 | if (false === $this->getHelper()->hasFullWebsiteAccess($website)) {
70 | return $this->denyAccess($controller);
71 | }
72 | } else {
73 | return $this->denyAccess($controller);
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Build Status
2 | ---
3 | [](https://travis-ci.org/magento-hackathon/AdvancedAcl)
4 |
5 | # Extended Access Control List for Magento
6 |
7 | This extension allows merchants to restrict admin users to specific store views,
8 | so it makes your Magento multitenant.
9 |
10 | 
11 |
12 | ### What we can do
13 |
14 | We currently support restrictions of Magento Core:
15 |
16 | * system configuration,
17 | * customers
18 | * catalog, and
19 | * sales
20 |
21 | ### What we can't do
22 |
23 | There are lots of third party extensions for Magento and we can't support every
24 | single of them, so we focused on Magento Core, allowing you (or your developer)
25 | to extend it according to your needs.
26 |
27 | ## Installation
28 |
29 | We recommend to use [Composer](http://getcomposer.org) to install this into your
30 | Magento store, but you may also use
31 | [modman](https://github.com/colinmollenhour/modman) or just copy the extension
32 | into your Magento root.
33 |
34 | Most of our code uses event/observer pattern to gain maximum compatibility, but
35 | there are few rewrites, too (namely store switcher blocks). So make sure, your
36 | other extensions do not override the same blocks.
37 |
38 | Clean cache after installation.
39 |
40 | ## Usage
41 |
42 | Open System → Permissions → Roles and select a role without full system access.
43 | There you will find a new tab "Advanced ACL" in there, where you will be able to
44 | restrict the role to some specific store views.
45 |
46 | *If none is selected, the role access won't get limited.*
47 |
48 | Regarding system configuration, users will be able to enter website level, if
49 | they have access to all stores of the website. Furthermore, users will be able
50 | to enter default level, if they have access to all stores of your Magento
51 | installation.
52 |
53 | ## Extending
54 |
55 | Your shop probably contains lots of modules and you might want to restrict
56 | access to these, too.
57 |
58 | Our helper provides three methods to determine access:
59 |
60 | * ``Mage::helper('magentohackathon_advancedacl')->hasStoreViewAccess($store)``
61 | to request access to a specific store (given as Mage_Core_Model_Store, store
62 | id or store code),
63 | * ``Mage::helper('magentohackathon_advancedacl')->hasFullStoreGroupAccess($storegroup)``
64 | to request access to a whole storegroup (given as Mage_Core_Model_Store, store
65 | id or store code), that means, the user is allowed to
66 | access all stores of this store group,
67 | * ``Mage::helper('magentohackathon_advancedacl')->hasFullWebsiteAccess($website)``
68 | to request access to a whole website (given as Mage_Core_Model_Website,
69 | website id or website code), that means, the user is allowed to
70 | access all stores of this website,
71 | * ``Mage::helper('magentohackathon_advancedacl')->hasFullAccess()``
72 | to request access to the whole shop, that means, the user is allowed to
73 | access all stores of the shop
74 |
75 | Licence
76 | -------
77 | [OSL - Open Software Licence 3.0](http://opensource.org/licenses/osl-3.0.php)
78 |
79 | Copyright
80 | ---------
81 | (c) 2015
82 |
--------------------------------------------------------------------------------
/app/code/community/MagentoHackathon/AdvancedAcl/Model/Observer/Catalog.php:
--------------------------------------------------------------------------------
1 | getCollection();
14 | if ($collection instanceof Mage_Catalog_Model_Resource_Product_Collection) {
15 | $storeIds = $this->getStoreIds();
16 |
17 | if (!empty($storeIds)) {
18 | $collection->addStoreFilter(current($storeIds));
19 | }
20 | }
21 | }
22 |
23 | /**
24 | * filter url rewrite collection by allowed stores
25 | *
26 | * @param Varien_Event_Observer $observer
27 | */
28 | public function filterUrlRewriteCollection(Varien_Event_Observer $observer)
29 | {
30 | $collection = $observer->getCollection();
31 | if ($collection instanceof Mage_Core_Model_Resource_Url_Rewrite_Collection) {
32 | $storeIds = $this->getStoreIds();
33 | if (!empty($storeIds)) {
34 | $collection->addStoreFilter($storeIds);
35 | }
36 | }
37 | }
38 |
39 | /**
40 | * filter search terms by allowed stores
41 | *
42 | * @param Varien_Event_Observer $observer
43 | */
44 | public function filterSearchTermsGrid(Varien_Event_Observer $observer)
45 | {
46 | $collection = $observer->getCollection();
47 | if ($collection instanceof Mage_CatalogSearch_Model_Resource_Query_Collection) {
48 | $storeIds = $this->getStoreIds();
49 | if (!empty($storeIds)) {
50 | $collection->addStoreFilter($storeIds);
51 | }
52 | }
53 | }
54 | /**
55 | * filter search terms by allowed stores
56 | *
57 | * @param Varien_Event_Observer $observer
58 | */
59 | public function filterTagGrid(Varien_Event_Observer $observer)
60 | {
61 | $collection = $observer->getCollection();
62 | if ($collection instanceof Mage_Tag_Model_Resource_Tag_Collection) {
63 | $storeIds = $this->getStoreIds();
64 | if (!empty($storeIds)) {
65 | $collection->addStoreFilter($storeIds);
66 | }
67 | }
68 | }
69 |
70 | /**
71 | * filter out categories by allowed stores
72 | *
73 | * @param Varien_Event_Observer $observer
74 | */
75 | public function filterCategories(Varien_Event_Observer $observer)
76 | {
77 | /** @var Mage_Catalog_Model_Resource_Category_Collection $collection */
78 | $collection = $observer->getCategoryCollection();
79 | $storeIds = $this->getStoreIds();
80 | $oldStoreId = $collection->getStoreId();
81 | // setting the first allowed store if the current store is not allowed for user
82 | if (!empty($storeIds) && !in_array($oldStoreId, $storeIds)) {
83 | $allowedStoreId = current($storeIds);
84 | $collection
85 | ->setProductStoreId($allowedStoreId)
86 | ->setStoreId($allowedStoreId);
87 | }
88 | }
89 |
90 | /**
91 | * retrieves allowed store ids
92 | *
93 | * @return mixed
94 | */
95 | protected function getStoreIds()
96 | {
97 | return Mage::helper('magentohackathon_advancedacl/data')->getActiveRole()->getStoreIds();
98 | }
99 | }
--------------------------------------------------------------------------------
/app/code/community/MagentoHackathon/AdvancedAcl/Block/Adminhtml/Store/Switcher.php:
--------------------------------------------------------------------------------
1 | hasFullAccess()) {
43 | $this->_hasDefaultOption = false;
44 | }
45 | }
46 |
47 | public function isShow()
48 | {
49 | $helper = Mage::helper('magentohackathon_advancedacl');
50 | if (false === $helper->isSingleStoreMode()) {
51 | return true;
52 | }
53 | return parent::isShow();
54 | }
55 |
56 | /**
57 | * Get websites
58 | *
59 | * @return array
60 | */
61 | public function getWebsites()
62 | {
63 | $helper = Mage::helper('magentohackathon_advancedacl');
64 | $websites = parent::getWebsites();
65 | $result = array();
66 | foreach($websites as $website) {
67 | foreach ($website->getStores() as $store) {
68 | if ($helper->hasStoreViewAccess($store)) {
69 | $result[] = $website;
70 | break;
71 | }
72 | }
73 | }
74 | return $result;
75 | }
76 |
77 | /**
78 | * Get store groups for specified website
79 | *
80 | * @param Mage_Core_Model_Website $website
81 | * @return array
82 | */
83 | public function getStoreGroups($website)
84 | {
85 | $helper = Mage::helper('magentohackathon_advancedacl');
86 | $storeGroups = parent::getStoreGroups($website);
87 | $result = array();
88 | foreach($storeGroups as $key=>$storeGroup) {
89 | foreach ($storeGroups->getStores() as $store) {
90 | if ($helper->hasStoreViewAccess($store)) {
91 | $result[$key] = $storeGroup;
92 | break;
93 | }
94 | }
95 | }
96 | return $result;
97 | }
98 |
99 | /**
100 | * Get store views for specified store group
101 | *
102 | * @param Mage_Core_Model_Store_Group $group
103 | * @return array
104 | */
105 | public function getStores($group)
106 | {
107 | $helper = Mage::helper('magentohackathon_advancedacl');
108 | $stores = parent::getStores($group);
109 | $result = array();
110 | foreach($stores as $key=>$store) {
111 | if ($helper->hasStoreViewAccess($store)) {
112 | $result[$key] = $store;
113 | }
114 | }
115 | return $result;
116 | }
117 |
118 | }
119 |
--------------------------------------------------------------------------------
/app/code/community/MagentoHackathon/AdvancedAcl/Model/Observer/Sales.php:
--------------------------------------------------------------------------------
1 | getOrderGridCollection();
14 | $this->filterCollection($collection);
15 |
16 | }
17 |
18 | /**
19 | * filter sales order invoices collection by allowed stores
20 | *
21 | * @param Varien_Event_Observer $observer
22 | */
23 | public function filterInvoiceGrid(Varien_Event_Observer $observer)
24 | {
25 | $collection = $observer->getOrderInvoiceGridCollection();
26 | $this->filterCollection($collection);
27 | }
28 |
29 | /**
30 | * filters shipment grid by allowed stores
31 | *
32 | * @param Varien_Event_Observer $observer
33 | */
34 | public function filterShipmentsGrid(Varien_Event_Observer $observer)
35 | {
36 | $collection = $observer->getOrderShipmentGridCollection();
37 | $this->filterCollection($collection);
38 | }
39 |
40 |
41 | /**
42 | * filters credit memos grid by allowed stores
43 | *
44 | * @param Varien_Event_Observer $observer
45 | */
46 | public function filterCreditMemoGrid(Varien_Event_Observer $observer)
47 | {
48 | $collection = $observer->getOrderCreditmemoGridCollection();
49 | $this->filterCollection($collection);
50 | }
51 |
52 | public function filterAgreements(Varien_Event_Observer $observer)
53 | {
54 | $collection = $observer->getOrderCreditmemoGridCollection();
55 | $this->filterCollection($collection);
56 | }
57 |
58 | /**
59 | * filters agreements grid by allowed stores
60 | *
61 | * @param Varien_Event_Observer $observer
62 | */
63 | public function filterAgreementsGrid(Varien_Event_Observer $observer)
64 | {
65 | $collection = $observer->getCollection();
66 | if ($collection instanceof Mage_Checkout_Model_Resource_Agreement_Collection) {
67 | // getStoreIds() includes a DB query, so only execute this if this is the correct collection!
68 | $storeIds = $this->getStoreIds();
69 | if (! empty($storeIds) && ! in_array(Mage_Core_Model_App::ADMIN_STORE_ID, $storeIds)) {
70 | $collection->setIsStoreFilterWithAdmin(false);
71 | $collection->addStoreFilter($storeIds);
72 | }
73 | }
74 | if ($collection instanceof Mage_Sales_Model_Resource_Order_Payment_Transaction_Collection) {
75 | // getStoreIds() includes a DB query, so only execute this if this is the correct collection!
76 | $storeIds = $this->getStoreIds();
77 | $collection->addStoreFilter($storeIds);
78 | }
79 | }
80 |
81 |
82 | /**
83 | * filters recurring profile grid by allowed stores
84 | *
85 | * @param Varien_Event_Observer $observer
86 | */
87 | public function filterRecurringProfilesGrid(Varien_Event_Observer $observer)
88 | {
89 | /** @var Mage_Sales_Model_Resource_Recurring_Profile_Collection $collection */
90 | $collection = $observer->getRecurringProfileCollection();
91 | $storeIds = $this->getStoreIds();
92 | if (0 < count($storeIds)) {
93 | $collection->addFieldToFilter('store_id', array('in' => $storeIds));
94 | }
95 | }
96 |
97 |
98 | /**
99 | * retrieves allowed store ids
100 | *
101 | * @return mixed
102 | */
103 | protected function getStoreIds()
104 | {
105 | return Mage::helper('magentohackathon_advancedacl/data')->getActiveRole()->getStoreIds();
106 | }
107 |
108 | /**
109 | * @param $collection
110 | */
111 | public function filterCollection($collection)
112 | {
113 | $storeIds = $this->getStoreIds();
114 | if (0 < count($storeIds)) {
115 | $collection->addAttributeToFilter('store_id', array('in' => $storeIds));
116 | }
117 | }
118 |
119 | }
120 |
--------------------------------------------------------------------------------
/app/code/community/MagentoHackathon/AdvancedAcl/Block/Adminhtml/Permissions/Tab/Stores.php:
--------------------------------------------------------------------------------
1 |
33 | */
34 |
35 | class MagentoHackathon_AdvancedAcl_Block_Adminhtml_Permissions_Tab_Stores
36 | extends Mage_Adminhtml_Block_Widget_Form
37 | implements Mage_Adminhtml_Block_Widget_Tab_Interface
38 | {
39 | /**
40 | * @return MagentoHackathon_AdvancedAcl_Helper_Data
41 | */
42 | protected function _getHelper()
43 | {
44 | return Mage::helper('magentohackathon_advancedacl');
45 | }
46 |
47 | protected function _initForm()
48 | {
49 | $form = new Varien_Data_Form();
50 | $fieldset = $form->addFieldset('base_fieldset', array(
51 | 'legend' => Mage::helper('adminhtml')->__('Restrict store view access'))
52 | );
53 |
54 | /**
55 | * Check is single store mode
56 | */
57 | if (!$this->_getHelper()->isSingleStoreMode()) {
58 | $field = $fieldset->addField('store_ids', 'multiselect', array(
59 | 'name' => 'stores[]',
60 | 'label' => Mage::helper('cms')->__('Store View'),
61 | 'title' => Mage::helper('cms')->__('Store View'),
62 | 'values' => Mage::getSingleton('adminhtml/system_store')->getStoreValuesForForm(),
63 | ));
64 | $renderer = $this->getLayout()->createBlock('adminhtml/store_switcher_form_renderer_fieldset_element');
65 | $field->setRenderer($renderer);
66 | }
67 | else {
68 | $fieldset->addField('store_ids', 'hidden', array(
69 | 'name' => 'stores[]',
70 | 'value' => Mage::app()->getStore(true)->getId()
71 | ));
72 | }
73 |
74 | $form->setValues($this->getRole()->getData());
75 | $this->setForm($form);
76 | }
77 |
78 | /**
79 | *
80 | */
81 | protected function _beforeToHtml()
82 | {
83 | $this->_initForm();
84 | parent::_beforeToHtml();
85 | }
86 |
87 | /**
88 | *
89 | * @return Mage_Admin_Model_Roles
90 | */
91 | protected function getRole()
92 | {
93 | return Mage::registry('current_role');
94 | }
95 |
96 | /**
97 | *
98 | * @return Mage_Admin_Model_Roles
99 | */
100 | protected function getRoles()
101 | {
102 | return $this->getRole();
103 | }
104 |
105 | /**
106 | *
107 | * @return MagentoHackathon_AdvancedAcl_Helper_Data
108 | */
109 | protected function _helper()
110 | {
111 | return Mage::helper('magentohackathon_advancedacl');
112 | }
113 |
114 |
115 | public function canShowTab()
116 | {
117 | return true;
118 | }
119 |
120 | public function getTabLabel()
121 | {
122 | return Mage::helper('magentohackathon_advancedacl')->__('Advanced ACL');
123 | }
124 |
125 | public function getTabTitle()
126 | {
127 | return $this->getTabLabel();
128 | }
129 |
130 | public function isHidden()
131 | {
132 | return false;
133 | }
134 |
135 | }
136 |
--------------------------------------------------------------------------------
/app/code/community/MagentoHackathon/AdvancedAcl/Model/Observer/Role.php:
--------------------------------------------------------------------------------
1 |
33 | */
34 |
35 |
36 | /**
37 | * Class MagentoHackathon_AdvancedAcl_Model_Observer_Role
38 | */
39 | class MagentoHackathon_AdvancedAcl_Model_Observer_Role
40 | {
41 |
42 | /**
43 | * Add store restriction tab
44 | *
45 | * @param Varien_Event $event
46 | */
47 | public function addTabToRoles($event)
48 | {
49 | $block = $event->getBlock();
50 |
51 | /* @var Mage_Adminhtml_Block_Permissions_Editroles $block */
52 | if ($block instanceof Mage_Adminhtml_Block_Permissions_Editroles
53 | && Mage::helper('magentohackathon_advancedacl')->isAdmin()
54 | ) {
55 | $tab = $block->getLayout()->createBlock(
56 | 'magentohackathon_advancedacl/adminhtml_permissions_tab_stores',
57 | 'adminhtml.permissions.tab.magentohackathon_advancedacl'
58 | );
59 | $block->addTab('magentohackathon_advancedacl', $tab);
60 | }
61 | }
62 |
63 | /**
64 | * @param $roleId
65 | * @return mixed
66 | */
67 | public function lookupStoreIds($roleId)
68 | {
69 | $adapter = $this->_getReadAdapter();
70 |
71 | $select = $adapter->select()
72 | ->from($this->_getTable('magentohackathon_advancedacl/role_store'), 'store_id')
73 | ->where('role_id = ?',(int)$roleId);
74 |
75 | return $adapter->fetchCol($select);
76 | }
77 |
78 | /**
79 | * @return mixed
80 | */
81 | protected function _getReadAdapter()
82 | {
83 | return Mage::getSingleton('core/resource')->getConnection('core_read');
84 | }
85 |
86 | /**
87 | * @return mixed
88 | */
89 | protected function _getWriteAdapter()
90 | {
91 | return Mage::getSingleton('core/resource')->getConnection('core_write');
92 | }
93 |
94 | /**
95 | * @param $tableName
96 | * @return mixed
97 | */
98 | protected function _getTable($tableName)
99 | {
100 | return Mage::getSingleton('core/resource')->getTableName($tableName);
101 | }
102 |
103 | /**
104 | * @param Varien_Event_Observer $observer
105 | */
106 | public function addStoresToRoleModel(Varien_Event_Observer $observer)
107 | {
108 | /** @var Mage_Admin_Model_Roles $role */
109 | $role = $observer->getObject();
110 | /** @var Mage_Core_Controller_Request_Http $request */
111 | $request = $observer->getRequest();
112 |
113 | if ($stores = $request->getParam('stores')) {
114 | $role->setStores($stores);
115 | }
116 | }
117 |
118 | /**
119 | * @param Varien_Event_Observer $observer
120 | */
121 | public function saveAfter(Varien_Event_Observer $observer)
122 | {
123 | $object = $observer->getDataObject();
124 |
125 | if ($object instanceof Mage_Admin_Model_Roles) {
126 | if ($object->getStores()) {
127 | $oldStores = $this->lookupStoreIds($object->getId());
128 | $newStores = (array)$object->getStores();
129 | if (empty($newStores)) {
130 | $newStores = (array)$object->getStoreId();
131 | }
132 | $table = $this->_getTable('magentohackathon_advancedacl/role_store');
133 | $insert = array_diff($newStores, $oldStores);
134 | $delete = array_diff($oldStores, $newStores);
135 |
136 | if ($delete) {
137 | $where = array(
138 | 'role_id = ?' => (int) $object->getId(),
139 | 'store_id IN (?)' => $delete
140 | );
141 |
142 | $this->_getWriteAdapter()->delete($table, $where);
143 | }
144 |
145 | if ($insert) {
146 | $data = array();
147 |
148 | foreach ($insert as $storeId) {
149 | $data[] = array(
150 | 'role_id' => (int) $object->getId(),
151 | 'store_id' => (int) $storeId
152 | );
153 | }
154 | $this->_getWriteAdapter()->insertMultiple($table, $data);
155 | }
156 | }
157 | }
158 | }
159 |
160 | /**
161 | * @param Varien_Event_Observer $observer
162 | */
163 | public function afterLoad(Varien_Event_Observer $observer)
164 | {
165 | $object = $observer->getDataObject();
166 | if ($object->getId()) {
167 | $stores = $this->lookupStoreIds($object->getId());
168 | $object->setData('store_ids', $stores);
169 | }
170 | }
171 |
172 | /**
173 | * @param Varien_Event_Observer $observer
174 | */
175 | public function beforeDelete(Varien_Event_Observer $observer)
176 | {
177 | $object = $observer->getDataObject();
178 |
179 | if ($object->getId()) {
180 | $condition = array(
181 | 'role_id = ?' => (int)$object->getId(),
182 | );
183 | $this->_getWriteAdapter()->delete($this->_getTable('magentohackathon_advancedacl/role_store'), $condition);
184 | }
185 | }
186 | }
187 |
--------------------------------------------------------------------------------
/app/code/community/MagentoHackathon/AdvancedAcl/Helper/Data.php:
--------------------------------------------------------------------------------
1 |
33 | * @author Thomas Birke
34 | */
35 |
36 | class MagentoHackathon_AdvancedAcl_Helper_Data
37 | extends Mage_Core_Helper_Abstract
38 | {
39 |
40 | protected $_websites = null;
41 |
42 | /**
43 | * @var null|boolean
44 | */
45 | protected $_isSingleStoreMode = null;
46 |
47 | /**
48 | * if customer is allowed to access given store
49 | *
50 | * @param int|string|Mage_Core_Model_Store $store store id, store code, or store
51 | * @return bool
52 | */
53 | public function hasStoreViewAccess($store = null)
54 | {
55 | if (is_null($store)) {
56 | $store = $this->getDefaultStoreId();
57 | }
58 | if (is_object($store) && $store instanceof Mage_Core_Model_Store) {
59 | $storeId = $store->getId();
60 | } elseif (is_numeric($store)) {
61 | $storeId = $store;
62 | } else {
63 | $storeId = Mage::getModel('core/store')->load($store)->getId();
64 | }
65 | $allowedStores = $this->getActiveRole()->getStoreIds();
66 |
67 | return empty($allowedStores) || in_array($storeId, $allowedStores);
68 | }
69 |
70 | /**
71 | * get stores the customer is restricted to
72 | *
73 | * @return array
74 | * @codeCoverageIgnore
75 | */
76 | public function getAllowedStoreIds()
77 | {
78 | return $this->getActiveRole()->getStoreIds();
79 | }
80 |
81 | /**
82 | * if customer is restricted to specific stores
83 | *
84 | * @return bool
85 | */
86 | public function hasFullAccess()
87 | {
88 | $allowedStoreIds = $this->getAllowedStoreIds();
89 |
90 | return empty($allowedStoreIds)
91 | || Mage::getModel('core/store')->getCollection()->getAllIds() === $allowedStoreIds;
92 | }
93 |
94 | /**
95 | * if customer can access all stores of a website
96 | *
97 | * @param Mage_Core_Model_Website|string $website Website to check stores of
98 | * @return bool
99 | */
100 | public function hasFullWebsiteAccess($website)
101 | {
102 | if (is_string($website)) {
103 | $website = Mage::getModel('core/website')->load($website);
104 | }
105 |
106 | $diff = array_diff($website->getStoreIds(), $this->getAllowedStoreIds());
107 | return empty($diff);
108 | }
109 |
110 | /**
111 | * if customer can access all stores of a store group
112 | *
113 | * @param Mage_Core_Model_Store_Group|string $group Group to check stores of
114 | * @return bool
115 | */
116 | public function hasFullStoreGroupAccess($storeGroup)
117 | {
118 | if (is_string($storeGroup)) {
119 | $storeGroup = Mage::getModel('core/store_group')->load($storeGroup);
120 | }
121 |
122 | $diff = array_diff($storeGroup->getStoreIds(), $this->getAllowedStoreIds());
123 | return empty($diff);
124 | }
125 |
126 | /**
127 | * @param int $roleid role_id from admin/role
128 | * @return boolean
129 | * @codeCoverageIgnore
130 | */
131 | public function isAdmin()
132 | {
133 | $collection = Mage::getModel('admin/rules')
134 | ->getCollection()
135 | ->addFieldToFilter('role_id', $this->getActiveRole()->getId())
136 | ->addFieldToFilter('resource_id', 'all')
137 | ->addFieldToFilter('permission', 'allow');
138 | if($collection->count() > 0)
139 | {
140 | return true;
141 | }
142 | return false;
143 | }
144 |
145 | /**
146 | *
147 | * @return Mage_Admin_Model_Role
148 | * @codeCoverageIgnore
149 | */
150 | public function getActiveRole()
151 | {
152 | $user = Mage::getSingleton('admin/session')->getUser();
153 | if ($user === null) {
154 | // this can happen on API calls - make sure to use an administrator with all rights then!
155 | // we should not filter any collection for API calls since our restrictions are defined per admin-user
156 | // we currently do not have any restrictions for API users
157 | $adminRoleId = Mage::getModel('admin/rules')
158 | ->getCollection()
159 | ->addFieldToFilter('resource_id', Mage_Admin_Model_Resource_Acl::ACL_ALL_RULES)
160 | ->addFieldToFilter('permission', Mage_Admin_Model_Rules::RULE_PERMISSION_ALLOWED)
161 | ->setPageSize(1)
162 | ->setCurPage(1)
163 | ->getFirstItem()
164 | ->getData('role_id');
165 |
166 | return Mage::getModel('admin/role')->load($adminRoleId);
167 | }
168 |
169 | return $user->getRole();
170 | }
171 |
172 | /**
173 | * Is single Store mode (only one store without default)
174 | *
175 | * @return bool|null
176 | * @codeCoverageIgnore
177 | */
178 | public function isSingleStoreMode()
179 | {
180 | if (is_null($this->_isSingleStoreMode)) {
181 | $this->_isSingleStoreMode = Mage::app()->isSingleStoreMode();
182 | }
183 | return $this->_isSingleStoreMode;
184 | }
185 |
186 | /**
187 | * get the default store-id
188 | *
189 | * @return mixed
190 | * @throws Mage_Core_Exception
191 | * @codeCoverageIgnore
192 | */
193 | public function getDefaultStoreId()
194 | {
195 | return Mage::app()
196 | ->getWebsite(true)
197 | ->getDefaultGroup()
198 | ->getDefaultStoreId();
199 | }
200 | }
201 |
--------------------------------------------------------------------------------
/app/code/community/MagentoHackathon/AdvancedAcl/Test/Helper/DataTests.php:
--------------------------------------------------------------------------------
1 | getModelMock('admin/roles', array('__call'));
18 |
19 | $rolesMock->expects($this->once())
20 | ->method('__call')
21 | ->with('getStoreIds')
22 | ->will($this->returnValue(array(1)));
23 |
24 | $this->replaceByMock('model', 'admin/roles', $rolesMock);
25 |
26 | $helperMock = $this->getHelperMock(self::HELPER_ALIAS, array('getDefaultStoreId', 'getActiveRole'));
27 |
28 | $helperMock->expects($this->once())
29 | ->method('getDefaultStoreId')
30 | ->will($this->returnValue(1));
31 |
32 | $helperMock->expects($this->once())
33 | ->method('getActiveRole')
34 | ->will($this->returnValue($rolesMock));
35 |
36 | $this->replaceByMock('helper', self::HELPER_ALIAS, $helperMock);
37 |
38 | $this->assertTrue(
39 | Mage::helper(self::HELPER_ALIAS)->hasStoreViewAccess()
40 | );
41 |
42 | $rolesMock = $this->getModelMock('admin/roles', array('__call'));
43 |
44 | $rolesMock->expects($this->once())
45 | ->method('__call')
46 | ->with('getStoreIds')
47 | ->will($this->returnValue(array(2)));
48 |
49 | $this->replaceByMock('model', 'admin/roles', $rolesMock);
50 |
51 | $helperMock = $this->getHelperMock(self::HELPER_ALIAS, array('getDefaultStoreId', 'getActiveRole'));
52 |
53 | $helperMock->expects($this->once())
54 | ->method('getDefaultStoreId')
55 | ->will($this->returnValue(1));
56 |
57 | $helperMock->expects($this->once())
58 | ->method('getActiveRole')
59 | ->will($this->returnValue($rolesMock));
60 |
61 | $this->replaceByMock('helper', self::HELPER_ALIAS, $helperMock);
62 |
63 | $this->assertFalse(
64 | Mage::helper(self::HELPER_ALIAS)->hasStoreViewAccess()
65 | );
66 |
67 | }
68 |
69 | public function testIsAllowedAccessForStoreWithStoreParam()
70 | {
71 | $rolesMock = $this->getModelMock('admin/roles', array('__call'));
72 |
73 | $rolesMock->expects($this->once())
74 | ->method('__call')
75 | ->with('getStoreIds')
76 | ->will($this->returnValue(array(1)));
77 |
78 | $this->replaceByMock('model', 'admin/roles', $rolesMock);
79 |
80 | $helperMock = $this->getHelperMock(self::HELPER_ALIAS, array('getDefaultStoreId', 'getActiveRole'));
81 |
82 | $helperMock->expects($this->once())
83 | ->method('getActiveRole')
84 | ->will($this->returnValue($rolesMock));
85 |
86 | $this->replaceByMock('helper', self::HELPER_ALIAS, $helperMock);
87 |
88 | $this->assertTrue(
89 | Mage::helper(self::HELPER_ALIAS)->hasStoreViewAccess(1)
90 | );
91 |
92 | $rolesMock = $this->getModelMock('admin/roles', array('__call'));
93 |
94 | $rolesMock->expects($this->once())
95 | ->method('__call')
96 | ->with('getStoreIds')
97 | ->will($this->returnValue(array(1)));
98 |
99 | $this->replaceByMock('model', 'admin/roles', $rolesMock);
100 |
101 | $helperMock = $this->getHelperMock(self::HELPER_ALIAS, array('getDefaultStoreId', 'getActiveRole'));
102 |
103 | $helperMock->expects($this->once())
104 | ->method('getActiveRole')
105 | ->will($this->returnValue($rolesMock));
106 |
107 | $this->replaceByMock('helper', self::HELPER_ALIAS, $helperMock);
108 |
109 | $this->assertFalse(
110 | Mage::helper(self::HELPER_ALIAS)->hasStoreViewAccess(2)
111 | );
112 | }
113 |
114 | public function testHasFullAccess()
115 | {
116 | $helperMock = $this->getHelperMock(self::HELPER_ALIAS, array('getAllowedStoreIds', 'getActiveRole'));
117 |
118 | $helperMock->expects($this->once())
119 | ->method('getAllowedStoreIds')
120 | ->will($this->returnValue(array(3,4)));
121 |
122 | $this->replaceByMock('helper', self::HELPER_ALIAS, $helperMock);
123 |
124 | $coreStoreCollectionMock = $this->getResourceModelMock('core/store_collection', array('getAllIds'));
125 |
126 | $coreStoreCollectionMock->expects($this->once())
127 | ->method('getAllIds')
128 | ->will($this->returnValue(array(3,4)));
129 |
130 | $this->replaceByMock('resource_model', 'core/store_collection', $coreStoreCollectionMock);
131 |
132 | $this->assertTrue(
133 | Mage::helper(self::HELPER_ALIAS)->hasFullAccess()
134 | );
135 |
136 | $helperMock = $this->getHelperMock(self::HELPER_ALIAS, array('getAllowedStoreIds', 'getActiveRole'));
137 |
138 | $helperMock->expects($this->once())
139 | ->method('getAllowedStoreIds')
140 | ->will($this->returnValue(array(3,4)));
141 |
142 | $this->replaceByMock('helper', self::HELPER_ALIAS, $helperMock);
143 |
144 | $coreStoreCollectionMock = $this->getResourceModelMock('core/store_collection', array('getAllIds'));
145 |
146 | $coreStoreCollectionMock->expects($this->once())
147 | ->method('getAllIds')
148 | ->will($this->returnValue(array(1,2,3,4,5)));
149 |
150 | $this->replaceByMock('resource_model', 'core/store_collection', $coreStoreCollectionMock);
151 |
152 | $this->assertFalse(
153 | Mage::helper(self::HELPER_ALIAS)->hasFullAccess()
154 | );
155 |
156 | }
157 |
158 | public function testHasFullWebsiteAccess()
159 | {
160 | $coreWebsiteModelMock = $this->getModelMock('core/website', array('getStoreIds'));
161 |
162 | $coreWebsiteModelMock->expects($this->once())
163 | ->method('getStoreIds')
164 | ->will($this->returnValue(array(13)));
165 |
166 | $this->replaceByMock('model', 'core/website', $coreWebsiteModelMock);
167 |
168 | $helperMock = $this->getHelperMock(self::HELPER_ALIAS, array('getAllowedStoreIds'));
169 |
170 | $helperMock->expects($this->once())
171 | ->method('getAllowedStoreIds')
172 | ->will($this->returnValue(array(13)));
173 |
174 | $this->replaceByMock('helper', self::HELPER_ALIAS, $helperMock);
175 |
176 | $this->assertTrue(
177 | Mage::helper(self::HELPER_ALIAS)->hasFullWebsiteAccess('dummy')
178 | );
179 |
180 | $coreWebsiteModelMock = $this->getModelMock('core/website', array('getStoreIds'));
181 |
182 | $coreWebsiteModelMock->expects($this->once())
183 | ->method('getStoreIds')
184 | ->will($this->returnValue(array(13)));
185 |
186 | $this->replaceByMock('model', 'core/website', $coreWebsiteModelMock);
187 |
188 | $helperMock = $this->getHelperMock(self::HELPER_ALIAS, array('getAllowedStoreIds'));
189 |
190 | $helperMock->expects($this->once())
191 | ->method('getAllowedStoreIds')
192 | ->will($this->returnValue(array(12)));
193 |
194 | $this->replaceByMock('helper', self::HELPER_ALIAS, $helperMock);
195 |
196 | $this->assertFalse(
197 | Mage::helper(self::HELPER_ALIAS)->hasFullWebsiteAccess('dummy')
198 | );
199 |
200 | $helperMock = $this->getHelperMock(self::HELPER_ALIAS, array('getAllowedStoreIds'));
201 |
202 | $helperMock->expects($this->once())
203 | ->method('getAllowedStoreIds')
204 | ->will($this->returnValue(array(12)));
205 |
206 | $this->replaceByMock('helper', self::HELPER_ALIAS, $helperMock);
207 |
208 | $this->assertTrue(
209 | Mage::helper(self::HELPER_ALIAS)->hasFullWebsiteAccess(
210 | (new Varien_Object())->setStoreIds(array(12))
211 | )
212 | );
213 |
214 | $helperMock = $this->getHelperMock(self::HELPER_ALIAS, array('getAllowedStoreIds'));
215 |
216 | $helperMock->expects($this->once())
217 | ->method('getAllowedStoreIds')
218 | ->will($this->returnValue(array(12)));
219 |
220 | $this->replaceByMock('helper', self::HELPER_ALIAS, $helperMock);
221 |
222 | $this->assertFalse(
223 | Mage::helper(self::HELPER_ALIAS)->hasFullWebsiteAccess(
224 | (new Varien_Object())->setStoreIds(array(2))
225 | )
226 | );
227 | }
228 |
229 | public function testHasFullStoreGroupAccess()
230 | {
231 | $coreStoreGroupModelMock = $this->getModelMock('core/store_group', array('getStoreIds'));
232 |
233 | $coreStoreGroupModelMock->expects($this->once())
234 | ->method('getStoreIds')
235 | ->will($this->returnValue(array(4,5,6)));
236 |
237 | $this->replaceByMock('model', 'core/store_group', $coreStoreGroupModelMock);
238 |
239 | $helperMock = $this->getHelperMock(self::HELPER_ALIAS, array('getAllowedStoreIds'));
240 |
241 | $helperMock->expects($this->once())
242 | ->method('getAllowedStoreIds')
243 | ->will($this->returnValue(array(4,5,6)));
244 |
245 | $this->replaceByMock('helper', self::HELPER_ALIAS, $helperMock);
246 |
247 | $this->assertTrue(
248 | Mage::helper(self::HELPER_ALIAS)->hasFullStoreGroupAccess('dummy')
249 | );
250 |
251 | $coreStoreGroupModelMock = $this->getModelMock('core/store_group', array('getStoreIds'));
252 |
253 | $coreStoreGroupModelMock->expects($this->once())
254 | ->method('getStoreIds')
255 | ->will($this->returnValue(array(5)));
256 |
257 | $this->replaceByMock('model', 'core/store_group', $coreStoreGroupModelMock);
258 |
259 | $helperMock = $this->getHelperMock(self::HELPER_ALIAS, array('getAllowedStoreIds'));
260 |
261 | $helperMock->expects($this->once())
262 | ->method('getAllowedStoreIds')
263 | ->will($this->returnValue(array(30)));
264 |
265 | $this->replaceByMock('helper', self::HELPER_ALIAS, $helperMock);
266 |
267 | $this->assertFalse(
268 | Mage::helper(self::HELPER_ALIAS)->hasFullStoreGroupAccess('dummy')
269 | );
270 |
271 | $this->replaceByMock('model', 'core/store_group', $coreStoreGroupModelMock);
272 |
273 | $helperMock = $this->getHelperMock(self::HELPER_ALIAS, array('getAllowedStoreIds'));
274 |
275 | $helperMock->expects($this->once())
276 | ->method('getAllowedStoreIds')
277 | ->will($this->returnValue(array(5)));
278 |
279 | $this->replaceByMock('helper', self::HELPER_ALIAS, $helperMock);
280 |
281 | $this->assertTrue(
282 | Mage::helper(self::HELPER_ALIAS)->hasFullStoreGroupAccess(
283 | (new Varien_Object())->setStoreIds(array(5))
284 | )
285 | );
286 |
287 | $this->replaceByMock('model', 'core/store_group', $coreStoreGroupModelMock);
288 |
289 | $helperMock = $this->getHelperMock(self::HELPER_ALIAS, array('getAllowedStoreIds'));
290 |
291 | $helperMock->expects($this->once())
292 | ->method('getAllowedStoreIds')
293 | ->will($this->returnValue(array(9)));
294 |
295 | $this->replaceByMock('helper', self::HELPER_ALIAS, $helperMock);
296 |
297 | $this->assertFalse(
298 | Mage::helper(self::HELPER_ALIAS)->hasFullStoreGroupAccess(
299 | (new Varien_Object())->setStoreIds(array(5))
300 | )
301 | );
302 |
303 | }
304 |
305 | }
--------------------------------------------------------------------------------
/app/code/community/MagentoHackathon/AdvancedAcl/etc/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 1.0.0
6 |
7 |
8 |
9 |
10 |
11 | MagentoHackathon_AdvancedAcl_Model
12 | magentohackathon_advancedacl_resource
13 |
14 |
15 | MagentoHackathon_AdvancedAcl_Model_Resource
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | MagentoHackathon_AdvancedAcl_Helper
26 |
27 |
28 |
29 |
30 | MagentoHackathon_AdvancedAcl_Block
31 |
32 |
33 |
34 | MagentoHackathon_AdvancedAcl_Block_Adminhtml_Store_Switcher
35 | MagentoHackathon_AdvancedAcl_Block_Adminhtml_System_Config_Switcher
36 |
37 |
38 |
39 |
40 |
41 |
42 | MagentoHackathon_AdvancedAcl
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | MagentoHackathon_AdvancedAcl.csv
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | singleton
62 | magentohackathon_advancedacl/observer_role
63 | addStoresToRoleModel
64 |
65 |
66 |
67 |
68 |
69 |
70 | singleton
71 | magentohackathon_advancedacl/observer_role
72 | saveAfter
73 |
74 |
75 |
76 |
77 |
78 |
79 | singleton
80 | magentohackathon_advancedacl/observer_role
81 | afterLoad
82 |
83 |
84 |
85 |
86 |
87 |
88 | singleton
89 | magentohackathon_advancedacl/observer_role
90 | beforeDelete
91 |
92 |
93 |
94 |
95 |
96 |
97 | singleton
98 | magentohackathon_advancedacl/observer_role
99 | addTabToRoles
100 |
101 |
102 |
103 |
104 |
105 |
106 | singleton
107 | magentohackathon_advancedacl/observer_sales
108 | filterOrderGrid
109 |
110 |
111 |
112 |
113 |
114 |
115 | singleton
116 | magentohackathon_advancedacl/observer_sales
117 | filterInvoiceGrid
118 |
119 |
120 |
121 |
122 |
123 |
124 | singleton
125 | magentohackathon_advancedacl/observer_sales
126 | filterShipmentsGrid
127 |
128 |
129 |
130 |
131 |
132 |
133 | singleton
134 | magentohackathon_advancedacl/observer_sales
135 | filterCreditMemoGrid
136 |
137 |
138 |
139 |
140 |
141 |
142 | singleton
143 | magentohackathon_advancedacl/observer_sales
144 | filterRecurringProfilesGrid
145 |
146 |
147 |
148 |
149 |
150 |
151 | singleton
152 | magentohackathon_advancedacl/observer_sales
153 | filterAgreementsGrid
154 |
155 |
156 | singleton
157 | magentohackathon_advancedacl/observer_catalog
158 | filterUrlRewriteCollection
159 |
160 |
161 | singleton
162 | magentohackathon_advancedacl/observer_catalog
163 | filterSearchTermsGrid
164 |
165 |
166 | singleton
167 | magentohackathon_advancedacl/observer_catalog
168 | filterTagGrid
169 |
170 |
171 |
172 |
173 |
174 |
175 | singleton
176 | magentohackathon_advancedacl/observer_catalog
177 | filterCategories
178 |
179 |
180 |
181 |
182 |
183 |
184 | singleton
185 | magentohackathon_advancedacl/observer_catalog
186 | filterProductGrid
187 |
188 |
189 | singleton
190 | magentohackathon_advancedacl/observer_customer
191 | filterCustomerGrid
192 |
193 |
194 |
195 |
196 |
197 |
198 | singleton
199 | magentohackathon_advancedacl/observer_config
200 | beforeLoad
201 |
202 |
203 |
204 |
205 |
206 |
207 | singleton
208 | magentohackathon_advancedacl/observer_access
209 | productEditAccessAllowed
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 | singleton
218 | magentohackathon_advancedacl/observer_url
219 | catalogProductEdit
220 |
221 |
222 |
223 |
224 |
225 |
226 | singleton
227 | magentohackathon_advancedacl/observer_url
228 | catalogCategoryEdit
229 |
230 |
231 |
232 |
233 |
234 |
235 | singleton
236 | magentohackathon_advancedacl/observer_url
237 | cmsPageIndex
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
--------------------------------------------------------------------------------