PageRenderTime 28ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://github.com/grandison/budo16
PHP | 524 lines | 379 code | 73 blank | 72 comment | 109 complexity | 88deabb09038da49342f764cff3c9bc1 MD5 | raw file
  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 7481 2010-09-27 08:41:01Z 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. if( empty($row->role_id) ) {
  80. $index = array_search($row->role, $this->_relationships);
  81. if( $index === false ) { // Invalid type
  82. continue;
  83. }
  84. $perms[$row->role] = $row;
  85. $permsByOrder[$index] = $row->role;
  86. } else {
  87. $items[] = $row;
  88. }
  89. }
  90. // We we're passed a type role, how convenient
  91. if( is_string($role) ) {
  92. if( isset($perms[$role]) && is_object($perms[$role]) && $perms[$role]->value == Authorization_Api_Core::LEVEL_ALLOW ) {
  93. return Authorization_Api_Core::LEVEL_ALLOW;
  94. } else {
  95. return Authorization_Api_Core::LEVEL_DISALLOW;
  96. }
  97. }
  98. // Scan available types
  99. foreach( $permsByOrder as $perm => $type ) {
  100. $row = $perms[$type];
  101. $method = 'is_' . $type;
  102. if( !method_exists($this, $method) ) continue;
  103. $applies = $this->$method($resource, $role);
  104. if( $applies && $row->value == Authorization_Api_Core::LEVEL_ALLOW ) {
  105. return Authorization_Api_Core::LEVEL_ALLOW;
  106. }
  107. }
  108. // Ok, lets check the items then
  109. foreach( $items as $row ) {
  110. if( !Engine_Api::_()->hasItemType($row->role) ) {
  111. continue;
  112. }
  113. // Item itself is auth'ed
  114. if( is_object($role) && $role->getType() == $row->role && $role->getIdentity() == $row->role_id ) {
  115. return Authorization_Api_Core::LEVEL_ALLOW;
  116. }
  117. // Get item class
  118. $itemClass = Engine_Api::_()->getItemClass($row->role);
  119. // Member of
  120. if( method_exists($itemClass, 'membership') ) {
  121. $item = Engine_Api::_()->getItem($row->role, $row->role_id);
  122. if( $item && $item->membership()->isMember($role, null, $row->subgroup_id) ) {
  123. return Authorization_Api_Core::LEVEL_ALLOW;
  124. }
  125. }
  126. // List
  127. else if( method_exists($itemClass, 'has') ) {
  128. $item = Engine_Api::_()->getItem($row->role, $row->role_id);
  129. if( $item && $item->has($role) ) {
  130. return Authorization_Api_Core::LEVEL_ALLOW;
  131. }
  132. }
  133. }
  134. return Authorization_Api_Core::LEVEL_DISALLOW;
  135. }
  136. public function getAllowed($resource, $role, $action)
  137. {
  138. // Non-boolean values are not yet implemented
  139. return $this->isAllowed($resource, $role, $action);
  140. }
  141. public function setAllowed($resource, $role, $action, $value = false, $role_id = 0)
  142. {
  143. // Can set multiple actions
  144. if( is_array($action) )
  145. {
  146. foreach( $action as $key => $value )
  147. {
  148. $this->setAllowed($resource, $role, $key, $value, $role_id);
  149. }
  150. return $this;
  151. }
  152. // Resource must be an instance of Core_Model_Item_Abstract
  153. if( !($resource instanceof Core_Model_Item_Abstract) )
  154. {
  155. throw new Authorization_Model_Exception('$resource must be an instance of Core_Model_Item_Abstract');
  156. }
  157. // Role must be a string, NOT a Core_Model_Item_Abstract
  158. //if( !is_string($role) )
  159. //{
  160. // throw new Authorization_Model_Exception('$role must be a string relationship type');
  161. //}
  162. // Ignore owner (since owner is allowed everything)
  163. if( $role === 'owner' ) {
  164. return $this;
  165. }
  166. if( is_string($role) ) {
  167. $role_id = 0;
  168. } else if( $role instanceof Core_Model_Item_Abstract ) {
  169. $role_id = $role->getIdentity();
  170. $role = $role->getType();
  171. }
  172. // Try to get an existing row
  173. $select = $this->select()
  174. ->where('resource_type = ?', $resource->getType())
  175. ->where('resource_id = ?', $resource->getIdentity())
  176. ->where('action = ?', $action)
  177. ->where('role = ?', $role)
  178. ->where('role_id = ?', $role_id)
  179. ->limit(1);
  180. $row = $this->fetchRow($select);
  181. $deleteOnDisallow = true;
  182. // Whoops, create a new row)
  183. if( null === $row && (!$deleteOnDisallow || $value) )
  184. {
  185. $row = $this->createRow();
  186. $row->resource_type = $resource->getType();
  187. $row->resource_id = $resource->getIdentity();
  188. $row->action = $action;
  189. $row->role = $role;
  190. $row->role_id = $role_id;
  191. }
  192. if( null !== $row ) {
  193. if( !$deleteOnDisallow || $value ) {
  194. $row->value = (bool) $value;
  195. $row->save();
  196. } else if( $deleteOnDisallow && !$value ) {
  197. $row->delete();
  198. }
  199. }
  200. return $this;
  201. }
  202. protected function _getAllowed($resource, $role, $action)
  203. {
  204. // Make sure resource has an id (that it exists)
  205. $resource_type = $this->_getResourceType($resource);
  206. $resource_id = $this->_getResourceIdentity($resource);
  207. if( is_null($resource_id) )
  208. {
  209. return null;
  210. }
  211. // Get permissions
  212. $select = $this->select()
  213. ->where('resource_type = ?', $resource_type)
  214. ->where('resource_id = ?', $resource_id)
  215. ->where('action = ?', $action);
  216. //->where('role_type = ?', $role_guid[0])
  217. //->where('role_id = ?', $role_guid[1])
  218. return $this->fetchAll($select);
  219. }
  220. // Calculators
  221. // Tier 1
  222. public function is_everyone($resource, $role)
  223. {
  224. return true;
  225. }
  226. public function is_registered($resource, $role)
  227. {
  228. if( $role === 'registered' ) {
  229. return true;
  230. }
  231. if( !$role instanceof Core_Model_Item_Abstract ) {
  232. return false;
  233. }
  234. return (bool) $role->getIdentity();
  235. }
  236. public function is_member($resource, $role)
  237. {
  238. if( $role === 'member' ) {
  239. return true;
  240. }
  241. //if( !$role instanceof Core_Model_Item_Abstract ) {
  242. if( !$role instanceof User_Model_User ) {
  243. return false;
  244. }
  245. if( !method_exists($resource, 'membership') ) {
  246. return false;
  247. }
  248. return $resource->membership()->isMember($role, true);
  249. }
  250. public function is_member_requested($resource, $role)
  251. {
  252. if( $role === 'member_requested' ) {
  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. $info = $resource->membership()->getMemberInfo($role);
  263. return ( null !== $info && $info->resource_approved && !$info->active );
  264. }
  265. public function is_owner($resource, $role)
  266. {
  267. if( $role === 'owner' ) {
  268. return true;
  269. }
  270. if( !$role instanceof Core_Model_Item_Abstract ) {
  271. return false;
  272. }
  273. return $role->isSelf($resource->getOwner());
  274. }
  275. public function is_parent($resource, $role)
  276. {
  277. if( $role === 'parent' ) {
  278. return true;
  279. }
  280. if( !$role instanceof Core_Model_Item_Abstract ) {
  281. return false;
  282. }
  283. return $role->isSelf($resource->getParent());
  284. }
  285. // Tier 2
  286. public function is_owner_member($resource, $role)
  287. {
  288. if( $role === 'owner_member' ) {
  289. return true;
  290. }
  291. if( !($role instanceof Core_Model_Item_Abstract) || !($role instanceof User_Model_User) ) {
  292. return false;
  293. }
  294. $owner = $resource->getOwner();
  295. if( !method_exists($owner, 'membership') ) {
  296. return false;
  297. }
  298. return $owner->membership()->isMember($role, true);
  299. }
  300. public function is_parent_member($resource, $role)
  301. {
  302. if( $role === 'parent_member' ) {
  303. return true;
  304. }
  305. if( !($role instanceof Core_Model_Item_Abstract) || !($role instanceof User_Model_User) ) {
  306. return false;
  307. }
  308. $parent = $resource->getParent();
  309. if( !method_exists($parent, 'membership') ) {
  310. return false;
  311. }
  312. return $parent->membership()->isMember($role, true);
  313. }
  314. public function is_member_member($resource, $role)
  315. {
  316. // Note: this implies is_member
  317. if( $role === 'member_member' || $role == 'member' ) {
  318. return true;
  319. }
  320. if( !($role instanceof Core_Model_Item_Abstract) || !($role instanceof User_Model_User) ) {
  321. return false;
  322. }
  323. if( !method_exists($resource, 'membership') ) {
  324. return false;
  325. }
  326. if( $this->is_member($resource, $role) ) {
  327. return true;
  328. }
  329. $resourceMembershipTable = $resource->membership()->getReceiver();
  330. $userMembershipTable = $role->membership()->getReceiver();
  331. // Build
  332. $resourceMembershipTableName = $resourceMembershipTable->info('name');
  333. $userMembershipTableName = $userMembershipTable->info('name');
  334. $select = new Zend_Db_Select($resourceMembershipTable->getAdapter());
  335. $select
  336. ->from($resourceMembershipTableName, 'user_id')
  337. ->join($userMembershipTableName, "`{$resourceMembershipTableName}`.`user_id`=`{$userMembershipTableName}_2`.resource_id", null)
  338. ->where("`{$resourceMembershipTableName}`.resource_id = ?", $resource->getIdentity())
  339. ->where("`{$userMembershipTableName}_2`.user_id = ?", $role->getIdentity())
  340. ;
  341. $data = $select->query()->fetch();
  342. return !empty($data);
  343. }
  344. public function is_network($resource, $role)
  345. {
  346. if( $role === 'network' ) {
  347. return true;
  348. }
  349. if( !($role instanceof Core_Model_Item_Abstract) || !($role instanceof User_Model_User) ) {
  350. return false;
  351. }
  352. if( !($resource instanceof User_Model_User) ) {
  353. return false;
  354. }
  355. $networkMembershipTable = Engine_Api::_()->getDbtable('membership', 'network');
  356. $networkMembershipName = $networkMembershipTable->info('name');
  357. $select = new Zend_Db_Select($networkMembershipTable->getAdapter());
  358. $select
  359. ->from($networkMembershipName, 'user_id')
  360. ->join($networkMembershipName, "`{$networkMembershipName}`.`resource_id`=`{$networkMembershipName}_2`.resource_id", null)
  361. ->where("`{$networkMembershipName}`.user_id = ?", $resource->getIdentity())
  362. ->where("`{$networkMembershipName}_2`.user_id = ?", $role->getIdentity())
  363. ;
  364. $data = $select->query()->fetch();
  365. return !empty($data);
  366. }
  367. // Tier 3
  368. public function is_owner_member_member($resource, $role)
  369. {
  370. // Note: this implies is_owner_member
  371. if( $role === 'owner_member_member' || $role == 'owner_member' ) {
  372. return true;
  373. }
  374. if( !($role instanceof Core_Model_Item_Abstract) || !($role instanceof User_Model_User) ) {
  375. return false;
  376. }
  377. $owner = $resource->getOwner();
  378. return $this->is_member_member($owner, $role); // should work
  379. }
  380. public function is_parent_member_member($resource, $role)
  381. {
  382. // Note: this implies is_owner_member
  383. if( $role === 'parent_member_member' || $role == 'parent_member' ) {
  384. return true;
  385. }
  386. if( !($role instanceof Core_Model_Item_Abstract) || !($role instanceof User_Model_User) ) {
  387. return false;
  388. }
  389. $parent = $resource->getParent();
  390. return $this->is_member_member($parent, $role); // should work
  391. }
  392. public function is_owner_network($resource, $role)
  393. {
  394. if( $role === 'owner_network' ) {
  395. return true;
  396. }
  397. if( !($role instanceof Core_Model_Item_Abstract) || !($role instanceof User_Model_User) ) {
  398. return false;
  399. }
  400. $owner = $resource->getOwner();
  401. return $this->is_network($owner, $role); // should work
  402. }
  403. // Utility
  404. protected function _getResourceType($resource)
  405. {
  406. if( is_string($resource) )
  407. {
  408. return $resource;
  409. }
  410. else if( is_array($resource) && isset($resource[0]) )
  411. {
  412. return $resource[0];
  413. }
  414. else if( $resource instanceof Core_Model_Item_Abstract )
  415. {
  416. return $resource->getType();
  417. }
  418. else
  419. {
  420. return null;
  421. }
  422. }
  423. /**
  424. * Returns the identity of a resource from several possible formats:
  425. * Core_Model_Item_Abstract->getIdentity()
  426. * integer
  427. * array(type, identity)
  428. *
  429. * @param mixed $resource
  430. * @return mixed The identity of the resource
  431. */
  432. protected function _getResourceIdentity($resource)
  433. {
  434. if( is_numeric($resource) )
  435. {
  436. return $resource;
  437. }
  438. else if( is_array($resource) && isset($resource[1]) )
  439. {
  440. return $resource[1];
  441. }
  442. else if( $resource instanceof Core_Model_Item_Abstract )
  443. {
  444. return $resource->getIdentity();
  445. }
  446. else
  447. {
  448. return null;
  449. }
  450. }
  451. }