PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/application/modules/Authorization/Model/DbTable/Allow.php

https://github.com/shopaholiccompany/shopaholic
PHP | 538 lines | 393 code | 73 blank | 72 comment | 107 complexity | dd88cec1f769a53d9f53e0f2a9c083c8 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-3.0, LGPL-2.1
  1. <?php
  2. /**
  3. * SocialEngine
  4. *
  5. * @category Application_Core
  6. * @package Authorization
  7. * @copyright Copyright 2006-2010 Webligo Developments
  8. * @license http://www.socialengine.net/license/
  9. * @version $Id: Allow.php 7244 2010-09-01 01:49:53Z john $
  10. * @author John
  11. */
  12. /**
  13. * @category Application_Core
  14. * @package Authorization
  15. * @copyright Copyright 2006-2010 Webligo Developments
  16. * @license http://www.socialengine.net/license/
  17. */
  18. class Authorization_Model_DbTable_Allow extends Engine_Db_Table
  19. implements Authorization_Model_AdapterInterface
  20. {
  21. public function getAdapterName()
  22. {
  23. return 'context';
  24. }
  25. public function getAdapterPriority()
  26. {
  27. return 50;
  28. }
  29. /**
  30. * Valid relationship types. Ordered by speed of calculation
  31. *
  32. * @var array
  33. */
  34. protected $_relationships = array(
  35. 'everyone',
  36. 'registered',
  37. 'member',
  38. 'member_requested',
  39. 'owner',
  40. 'parent',
  41. 'owner_member',
  42. 'member_member',
  43. 'network',
  44. 'owner_member_member',
  45. 'owner_network'
  46. );
  47. public function isAllowed($resource, $role, $action)
  48. {
  49. // Resource must be an instance of Core_Model_Item_Abstract
  50. if( !($resource instanceof Core_Model_Item_Abstract) )
  51. {
  52. // We have nothing to say about generic permissions
  53. return Authorization_Api_Core::LEVEL_IGNORE;
  54. }
  55. // Role must be an instance of Core_Model_Item_Abstract or a string relationship type
  56. if( !($role instanceof Core_Model_Item_Abstract) && !is_string($role) )
  57. {
  58. // Disallow access to unknown role types
  59. return Authorization_Api_Core::LEVEL_DISALLOW;
  60. }
  61. // Owner can do what they want with the resource
  62. if( ($role instanceof Core_Model_Item_Abstract && method_exists($resource, 'isOwner') && $resource->isOwner($role)) || $role === 'owner' )
  63. {
  64. return Authorization_Api_Core::LEVEL_ALLOW;
  65. }
  66. // Now go over set permissions
  67. // @todo allow for custom types
  68. $rowset = $this->_getAllowed($resource, $role, $action);
  69. if( is_null($rowset) || !($rowset instanceof Engine_Db_Table_Rowset) )
  70. {
  71. // No permissions have been defined for resource, disallow all
  72. return Authorization_Api_Core::LEVEL_DISALLOW;
  73. }
  74. // Index by type
  75. $perms = array();
  76. $permsByOrder = array();
  77. $items = array();
  78. foreach( $rowset as $row )
  79. {
  80. if( empty($row->role_id) )
  81. {
  82. $index = array_search($row->role, $this->_relationships);
  83. if( $index === false ) { // Invalid type
  84. continue;
  85. }
  86. $perms[$row->role] = $row;
  87. $permsByOrder[$index] = $row->role;
  88. }
  89. else
  90. {
  91. $items[] = $row;
  92. }
  93. }
  94. // We we're passed a type role, how convenient
  95. if( is_string($role) )
  96. {
  97. if( isset($perms[$role]) && is_object($perms[$role]) && $perms[$role]->value == Authorization_Api_Core::LEVEL_ALLOW )
  98. {
  99. return Authorization_Api_Core::LEVEL_ALLOW;
  100. }
  101. else
  102. {
  103. return Authorization_Api_Core::LEVEL_DISALLOW;
  104. }
  105. }
  106. // Scan available types
  107. foreach( $permsByOrder as $perm => $type ) {
  108. $row = $perms[$type];
  109. $method = 'is_' . $type;
  110. if( !method_exists($this, $method) ) continue;
  111. $applies = $this->$method($resource, $role);
  112. if( $applies && $row->value == Authorization_Api_Core::LEVEL_ALLOW ) {
  113. return Authorization_Api_Core::LEVEL_ALLOW;
  114. }
  115. }
  116. // Ok, lets check the items then
  117. foreach( $items as $item ) {
  118. if( !Engine_Api::_()->hasItemType($row->role) )
  119. {
  120. continue;
  121. }
  122. // Item itself is auth'ed
  123. if( is_object($role) && $role->getType() == $row->role && $role->getIdentity() == $row->role_id )
  124. {
  125. return Authorization_Api_Core::LEVEL_ALLOW;
  126. }
  127. // Get item class
  128. $itemClass = Engine_Api::_()->getItemClass($row->role);
  129. // Member of
  130. if( method_exists($itemClass, 'membership') )
  131. {
  132. $item = Engine_Api::_()->getItem($row->role, $row->role_id);
  133. if( $item && $item->membership()->isMember($role, null, $row->subgroup_id))
  134. {
  135. return Authorization_Api_Core::LEVEL_ALLOW;
  136. }
  137. }
  138. // List
  139. else if( method_exists($itemClass, 'has') )
  140. {
  141. $item = Engine_Api::_()->getItem($row->role, $row->role_id);
  142. if( $item && $item->has($role) )
  143. {
  144. return Authorization_Api_Core::LEVEL_ALLOW;
  145. }
  146. }
  147. }
  148. return Authorization_Api_Core::LEVEL_DISALLOW;
  149. }
  150. public function getAllowed($resource, $role, $action)
  151. {
  152. // Non-boolean values are not yet implemented
  153. return $this->isAllowed($resource, $role, $action);
  154. }
  155. public function setAllowed($resource, $role, $action, $value = false, $role_id = 0)
  156. {
  157. // Can set multiple actions
  158. if( is_array($action) )
  159. {
  160. foreach( $action as $key => $value )
  161. {
  162. $this->setAllowed($resource, $role, $key, $value, $role_id);
  163. }
  164. return $this;
  165. }
  166. // Resource must be an instance of Core_Model_Item_Abstract
  167. if( !($resource instanceof Core_Model_Item_Abstract) )
  168. {
  169. throw new Authorization_Model_Exception('$resource must be an instance of Core_Model_Item_Abstract');
  170. }
  171. // Role must be a string, NOT a Core_Model_Item_Abstract
  172. //if( !is_string($role) )
  173. //{
  174. // throw new Authorization_Model_Exception('$role must be a string relationship type');
  175. //}
  176. // Ignore owner (since owner is allowed everything)
  177. if( $role === 'owner' ) {
  178. return $this;
  179. }
  180. if( is_string($role) ) {
  181. $role_id = 0;
  182. } else if( $role instanceof Core_Model_Item_Abstract ) {
  183. $role_id = $role->getIdentity();
  184. $role = $role->getType();
  185. }
  186. // Try to get an existing row
  187. $select = $this->select()
  188. ->where('resource_type = ?', $resource->getType())
  189. ->where('resource_id = ?', $resource->getIdentity())
  190. ->where('action = ?', $action)
  191. ->where('role = ?', $role)
  192. ->where('role_id = ?', $role_id)
  193. ->limit(1);
  194. $row = $this->fetchRow($select);
  195. $deleteOnDisallow = true;
  196. // Whoops, create a new row)
  197. if( null === $row && (!$deleteOnDisallow || $value) )
  198. {
  199. $row = $this->createRow();
  200. $row->resource_type = $resource->getType();
  201. $row->resource_id = $resource->getIdentity();
  202. $row->action = $action;
  203. $row->role = $role;
  204. $row->role_id = $role_id;
  205. }
  206. if( null !== $row ) {
  207. if( !$deleteOnDisallow || $value ) {
  208. $row->value = (bool) $value;
  209. $row->save();
  210. } else if( $deleteOnDisallow && !$value ) {
  211. $row->delete();
  212. }
  213. }
  214. return $this;
  215. }
  216. protected function _getAllowed($resource, $role, $action)
  217. {
  218. // Make sure resource has an id (that it exists)
  219. $resource_type = $this->_getResourceType($resource);
  220. $resource_id = $this->_getResourceIdentity($resource);
  221. if( is_null($resource_id) )
  222. {
  223. return null;
  224. }
  225. // Get permissions
  226. $select = $this->select()
  227. ->where('resource_type = ?', $resource_type)
  228. ->where('resource_id = ?', $resource_id)
  229. ->where('action = ?', $action);
  230. //->where('role_type = ?', $role_guid[0])
  231. //->where('role_id = ?', $role_guid[1])
  232. return $this->fetchAll($select);
  233. }
  234. // Calculators
  235. // Tier 1
  236. public function is_everyone($resource, $role)
  237. {
  238. return true;
  239. }
  240. public function is_registered($resource, $role)
  241. {
  242. if( $role === 'registered' ) {
  243. return true;
  244. }
  245. if( !$role instanceof Core_Model_Item_Abstract ) {
  246. return false;
  247. }
  248. return (bool) $role->getIdentity();
  249. }
  250. public function is_member($resource, $role)
  251. {
  252. if( $role === 'member' ) {
  253. return true;
  254. }
  255. //if( !$role instanceof Core_Model_Item_Abstract ) {
  256. if( !$role instanceof User_Model_User ) {
  257. return false;
  258. }
  259. if( !method_exists($resource, 'membership') ) {
  260. return false;
  261. }
  262. return $resource->membership()->isMember($role, true);
  263. }
  264. public function is_member_requested($resource, $role)
  265. {
  266. if( $role === 'member_requested' ) {
  267. return true;
  268. }
  269. //if( !$role instanceof Core_Model_Item_Abstract ) {
  270. if( !$role instanceof User_Model_User ) {
  271. return false;
  272. }
  273. if( !method_exists($resource, 'membership') ) {
  274. return false;
  275. }
  276. $info = $resource->membership()->getMemberInfo($role);
  277. return ( null !== $info && $info->resource_approved && !$info->active );
  278. }
  279. public function is_owner($resource, $role)
  280. {
  281. if( $role === 'owner' ) {
  282. return true;
  283. }
  284. if( !$role instanceof Core_Model_Item_Abstract ) {
  285. return false;
  286. }
  287. return $role->isSelf($resource->getOwner());
  288. }
  289. public function is_parent($resource, $role)
  290. {
  291. if( $role === 'parent' ) {
  292. return true;
  293. }
  294. if( !$role instanceof Core_Model_Item_Abstract ) {
  295. return false;
  296. }
  297. return $role->isSelf($resource->getParent());
  298. }
  299. // Tier 2
  300. public function is_owner_member($resource, $role)
  301. {
  302. if( $role === 'owner_member' ) {
  303. return true;
  304. }
  305. if( !($role instanceof Core_Model_Item_Abstract) || !($role instanceof User_Model_User) ) {
  306. return false;
  307. }
  308. $owner = $resource->getOwner();
  309. if( !method_exists($owner, 'membership') ) {
  310. return false;
  311. }
  312. return $owner->membership()->isMember($role, true);
  313. }
  314. public function is_parent_member($resource, $role)
  315. {
  316. if( $role === 'parent_member' ) {
  317. return true;
  318. }
  319. if( !($role instanceof Core_Model_Item_Abstract) || !($role instanceof User_Model_User) ) {
  320. return false;
  321. }
  322. $parent = $resource->getParent();
  323. if( !method_exists($parent, 'membership') ) {
  324. return false;
  325. }
  326. return $parent->membership()->isMember($role, true);
  327. }
  328. public function is_member_member($resource, $role)
  329. {
  330. // Note: this implies is_member
  331. if( $role === 'member_member' || $role == 'member' ) {
  332. return true;
  333. }
  334. if( !($role instanceof Core_Model_Item_Abstract) || !($role instanceof User_Model_User) ) {
  335. return false;
  336. }
  337. if( !method_exists($resource, 'membership') ) {
  338. return false;
  339. }
  340. if( $this->is_member($resource, $role) ) {
  341. return true;
  342. }
  343. $resourceMembershipTable = $resource->membership()->getReceiver();
  344. $userMembershipTable = $role->membership()->getReceiver();
  345. // Build
  346. $resourceMembershipTableName = $resourceMembershipTable->info('name');
  347. $userMembershipTableName = $userMembershipTable->info('name');
  348. $select = new Zend_Db_Select($resourceMembershipTable->getAdapter());
  349. $select
  350. ->from($resourceMembershipTableName, 'user_id')
  351. ->join($userMembershipTableName, "`{$resourceMembershipTableName}`.`user_id`=`{$userMembershipTableName}_2`.resource_id", null)
  352. ->where("`{$resourceMembershipTableName}`.resource_id = ?", $resource->getIdentity())
  353. ->where("`{$userMembershipTableName}_2`.user_id = ?", $role->getIdentity())
  354. ;
  355. $data = $select->query()->fetch();
  356. return !empty($data);
  357. }
  358. public function is_network($resource, $role)
  359. {
  360. if( $role === 'network' ) {
  361. return true;
  362. }
  363. if( !($role instanceof Core_Model_Item_Abstract) || !($role instanceof User_Model_User) ) {
  364. return false;
  365. }
  366. if( !($resource instanceof User_Model_User) ) {
  367. return false;
  368. }
  369. $networkMembershipTable = Engine_Api::_()->getDbtable('membership', 'network');
  370. $networkMembershipName = $networkMembershipTable->info('name');
  371. $select = new Zend_Db_Select($networkMembershipTable->getAdapter());
  372. $select
  373. ->from($networkMembershipName, 'user_id')
  374. ->join($networkMembershipName, "`{$networkMembershipName}`.`resource_id`=`{$networkMembershipName}_2`.resource_id", null)
  375. ->where("`{$networkMembershipName}`.user_id = ?", $resource->getIdentity())
  376. ->where("`{$networkMembershipName}_2`.user_id = ?", $role->getIdentity())
  377. ;
  378. $data = $select->query()->fetch();
  379. return !empty($data);
  380. }
  381. // Tier 3
  382. public function is_owner_member_member($resource, $role)
  383. {
  384. // Note: this implies is_owner_member
  385. if( $role === 'owner_member_member' || $role == 'owner_member' ) {
  386. return true;
  387. }
  388. if( !($role instanceof Core_Model_Item_Abstract) || !($role instanceof User_Model_User) ) {
  389. return false;
  390. }
  391. $owner = $resource->getOwner();
  392. return $this->is_member_member($owner, $role); // should work
  393. }
  394. public function is_parent_member_member($resource, $role)
  395. {
  396. // Note: this implies is_owner_member
  397. if( $role === 'parent_member_member' || $role == 'parent_member' ) {
  398. return true;
  399. }
  400. if( !($role instanceof Core_Model_Item_Abstract) || !($role instanceof User_Model_User) ) {
  401. return false;
  402. }
  403. $parent = $resource->getParent();
  404. return $this->is_member_member($parent, $role); // should work
  405. }
  406. public function is_owner_network($resource, $role)
  407. {
  408. if( $role === 'owner_network' ) {
  409. return true;
  410. }
  411. if( !($role instanceof Core_Model_Item_Abstract) || !($role instanceof User_Model_User) ) {
  412. return false;
  413. }
  414. $owner = $resource->getOwner();
  415. return $this->is_network($owner, $role); // should work
  416. }
  417. // Utility
  418. protected function _getResourceType($resource)
  419. {
  420. if( is_string($resource) )
  421. {
  422. return $resource;
  423. }
  424. else if( is_array($resource) && isset($resource[0]) )
  425. {
  426. return $resource[0];
  427. }
  428. else if( $resource instanceof Core_Model_Item_Abstract )
  429. {
  430. return $resource->getType();
  431. }
  432. else
  433. {
  434. return null;
  435. }
  436. }
  437. /**
  438. * Returns the identity of a resource from several possible formats:
  439. * Core_Model_Item_Abstract->getIdentity()
  440. * integer
  441. * array(type, identity)
  442. *
  443. * @param mixed $resource
  444. * @return mixed The identity of the resource
  445. */
  446. protected function _getResourceIdentity($resource)
  447. {
  448. if( is_numeric($resource) )
  449. {
  450. return $resource;
  451. }
  452. else if( is_array($resource) && isset($resource[1]) )
  453. {
  454. return $resource[1];
  455. }
  456. else if( $resource instanceof Core_Model_Item_Abstract )
  457. {
  458. return $resource->getIdentity();
  459. }
  460. else
  461. {
  462. return null;
  463. }
  464. }
  465. }