PageRenderTime 33ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/civicrm/CRM/Core/Permission/Base.php

https://github.com/nysenate/Bluebird-CRM
PHP | 418 lines | 181 code | 35 blank | 202 comment | 21 complexity | bad8261eb7edb23924bf5af7ee6ef82e MD5 | raw file
Possible License(s): JSON, BSD-3-Clause, MPL-2.0-no-copyleft-exception, AGPL-1.0, GPL-2.0, AGPL-3.0, Apache-2.0, MIT, GPL-3.0, CC-BY-4.0, LGPL-2.1, BSD-2-Clause, LGPL-3.0
  1. <?php
  2. /*
  3. +--------------------------------------------------------------------+
  4. | Copyright CiviCRM LLC. All rights reserved. |
  5. | |
  6. | This work is published under the GNU AGPLv3 license with some |
  7. | permitted exceptions and without any warranty. For full license |
  8. | and copyright information, see https://civicrm.org/licensing |
  9. +--------------------------------------------------------------------+
  10. */
  11. /**
  12. *
  13. * @package CRM
  14. * @copyright CiviCRM LLC https://civicrm.org/licensing
  15. */
  16. /**
  17. *
  18. */
  19. class CRM_Core_Permission_Base {
  20. /**
  21. * permission mapping to stub check() calls
  22. * @var array
  23. */
  24. public $permissions = NULL;
  25. /**
  26. * Is this user someone with access for the entire system.
  27. *
  28. * @var bool
  29. */
  30. protected $_viewAdminUser = FALSE;
  31. protected $_editAdminUser = FALSE;
  32. /**
  33. * Am in in view permission or edit permission?
  34. *
  35. * @var bool
  36. */
  37. protected $_viewPermission = FALSE;
  38. protected $_editPermission = FALSE;
  39. /**
  40. * Translate permission.
  41. *
  42. * @param string $perm
  43. * Permission string e.g "administer CiviCRM", "cms:access user record", "Drupal:administer content",
  44. * "Joomla:action:com_asset"
  45. *
  46. * @param string $nativePrefix
  47. * @param array $map
  48. * Array($portableName => $nativeName).
  49. *
  50. * @return NULL|string
  51. * a permission name
  52. */
  53. public function translatePermission($perm, $nativePrefix, $map) {
  54. [$civiPrefix, $name] = CRM_Utils_String::parsePrefix(':', $perm, NULL);
  55. switch ($civiPrefix) {
  56. case $nativePrefix:
  57. return $name;
  58. // pass through
  59. case 'cms':
  60. return CRM_Utils_Array::value($name, $map, CRM_Core_Permission::ALWAYS_DENY_PERMISSION);
  61. case NULL:
  62. return $name;
  63. default:
  64. return CRM_Core_Permission::ALWAYS_DENY_PERMISSION;
  65. }
  66. }
  67. /**
  68. * Get the current permission of this user.
  69. *
  70. * @return string
  71. * the permission of the user (edit or view or null)
  72. */
  73. public function getPermission() {
  74. $this->group();
  75. if ($this->_editPermission) {
  76. return CRM_Core_Permission::EDIT;
  77. }
  78. elseif ($this->_viewPermission) {
  79. return CRM_Core_Permission::VIEW;
  80. }
  81. return NULL;
  82. }
  83. /**
  84. * Get the permissioned where clause for the user.
  85. *
  86. * @param int $type
  87. * The type of permission needed.
  88. * @param array $tables
  89. * (reference ) add the tables that are needed for the select clause.
  90. * @param array $whereTables
  91. * (reference ) add the tables that are needed for the where clause.
  92. *
  93. * @return string
  94. * the group where clause for this user
  95. */
  96. public function whereClause($type, &$tables, &$whereTables) {
  97. return '( 1 )';
  98. }
  99. /**
  100. * Get the permissioned where clause for the user when trying to see groups.
  101. *
  102. * @param int $type
  103. * The type of permission needed.
  104. * @param array $tables
  105. * (reference ) add the tables that are needed for the select clause.
  106. * @param array $whereTables
  107. * (reference ) add the tables that are needed for the where clause.
  108. *
  109. * @return string
  110. * the group where clause for this user
  111. */
  112. public function getPermissionedStaticGroupClause($type, &$tables, &$whereTables) {
  113. $this->group();
  114. return $this->groupClause($type, $tables, $whereTables);
  115. }
  116. /**
  117. * Get all groups from database, filtered by permissions
  118. * for this user
  119. *
  120. * @param string $groupType
  121. * Type of group(Access/Mailing).
  122. * @param bool $excludeHidden
  123. * exclude hidden groups.
  124. *
  125. *
  126. * @return array
  127. * array reference of all groups.
  128. */
  129. public function group($groupType = NULL, $excludeHidden = TRUE) {
  130. $userId = CRM_Core_Session::getLoggedInContactID();
  131. $domainId = CRM_Core_Config::domainID();
  132. if (!isset(Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId])) {
  133. Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId] = Civi::$statics[__CLASS__]['editPermissionedGroups_' . $domainId . '_' . $userId] = [];
  134. }
  135. $groupKey = $groupType ? $groupType : 'all';
  136. if (!isset(Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey])) {
  137. Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey] = Civi::$statics[__CLASS__]['editPermissionedGroups_' . $domainId . '_' . $userId][$groupKey] = [];
  138. $groups = CRM_Core_PseudoConstant::allGroup($groupType, $excludeHidden);
  139. if ($this->check('edit all contacts')) {
  140. // this is the most powerful permission, so we return
  141. // immediately rather than dilute it further
  142. $this->_editAdminUser = $this->_viewAdminUser = TRUE;
  143. $this->_editPermission = $this->_viewPermission = TRUE;
  144. Civi::$statics[__CLASS__]['editPermissionedGroups_' . $domainId . '_' . $userId][$groupKey] = $groups;
  145. Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey] = $groups;
  146. return Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey];
  147. }
  148. elseif ($this->check('view all contacts')) {
  149. $this->_viewAdminUser = TRUE;
  150. $this->_viewPermission = TRUE;
  151. Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey] = $groups;
  152. }
  153. $ids = CRM_ACL_API::group(CRM_Core_Permission::VIEW, NULL, 'civicrm_saved_search', $groups);
  154. if (!empty($ids)) {
  155. foreach (array_values($ids) as $id) {
  156. $title = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $id, 'title');
  157. Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey][$id] = $title;
  158. $this->_viewPermission = TRUE;
  159. }
  160. }
  161. $ids = CRM_ACL_API::group(CRM_Core_Permission::EDIT, NULL, 'civicrm_saved_search', $groups);
  162. if (!empty($ids)) {
  163. foreach (array_values($ids) as $id) {
  164. $title = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $id, 'title');
  165. Civi::$statics[__CLASS__]['editPermissionedGroups_' . $domainId . '_' . $userId][$groupKey][$id] = $title;
  166. Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey][$id] = $title;
  167. $this->_editPermission = TRUE;
  168. $this->_viewPermission = TRUE;
  169. }
  170. }
  171. }
  172. return Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey];
  173. }
  174. /**
  175. * Get group clause for this user.
  176. *
  177. * @param int $type
  178. * The type of permission needed.
  179. * @param array $tables
  180. * (reference ) add the tables that are needed for the select clause.
  181. * @param array $whereTables
  182. * (reference ) add the tables that are needed for the where clause.
  183. *
  184. * @return string
  185. * the group where clause for this user
  186. */
  187. public function groupClause($type, &$tables, &$whereTables) {
  188. $userId = CRM_Core_Session::getLoggedInContactID();
  189. $domainId = CRM_Core_Config::domainID();
  190. if (!isset(Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId])) {
  191. $this->group();
  192. }
  193. // we basically get all the groups here
  194. $groupKey = 'all';
  195. if ($type == CRM_Core_Permission::EDIT) {
  196. if ($this->_editAdminUser) {
  197. $clause = ' ( 1 ) ';
  198. }
  199. elseif (empty(Civi::$statics[__CLASS__]['editPermissionedGroups_' . $domainId . '_' . $userId][$groupKey])) {
  200. $clause = ' ( 0 ) ';
  201. }
  202. else {
  203. $clauses = [];
  204. $groups = implode(', ', Civi::$statics[__CLASS__]['editPermissionedGroups_' . $domainId . '_' . $userId][$groupKey]);
  205. $clauses[] = ' ( civicrm_group_contact.group_id IN ( ' . implode(', ', array_keys(Civi::$statics[__CLASS__]['editPermissionedGroups_' . $domainId . '_' . $userId][$groupKey])) . " ) AND civicrm_group_contact.status = 'Added' ) ";
  206. $tables['civicrm_group_contact'] = 1;
  207. $whereTables['civicrm_group_contact'] = 1;
  208. // foreach group that is potentially a saved search, add the saved search clause
  209. foreach (array_keys(Civi::$statics[__CLASS__]['editPermissionedGroups_' . $domainId . '_' . $userId][$groupKey]) as $id) {
  210. $group = new CRM_Contact_DAO_Group();
  211. $group->id = $id;
  212. if ($group->find(TRUE) && $group->saved_search_id) {
  213. $clause = CRM_Contact_BAO_SavedSearch::whereClause($group->saved_search_id,
  214. $tables,
  215. $whereTables
  216. );
  217. if (trim($clause)) {
  218. $clauses[] = $clause;
  219. }
  220. }
  221. }
  222. $clause = ' ( ' . implode(' OR ', $clauses) . ' ) ';
  223. }
  224. }
  225. else {
  226. if ($this->_viewAdminUser) {
  227. $clause = ' ( 1 ) ';
  228. }
  229. elseif (empty(Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey])) {
  230. $clause = ' ( 0 ) ';
  231. }
  232. else {
  233. $clauses = [];
  234. $groups = implode(', ', Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey]);
  235. $clauses[] = ' civicrm_group.id IN (' . implode(', ', array_keys(Civi::$statics[__CLASS__]['viewPermissionedGroups_' . $domainId . '_' . $userId][$groupKey])) . " ) ";
  236. $tables['civicrm_group'] = 1;
  237. $whereTables['civicrm_group'] = 1;
  238. $clause = ' ( ' . implode(' OR ', $clauses) . ' ) ';
  239. }
  240. }
  241. return $clause;
  242. }
  243. /**
  244. * Given a permission string, check for access requirements
  245. *
  246. * @param string $str
  247. * The permission to check.
  248. * @param int $userId
  249. *
  250. * @return bool;
  251. *
  252. */
  253. public function check($str, $userId = NULL) {
  254. //no default behaviour
  255. return FALSE;
  256. }
  257. /**
  258. * Given a roles array, check for access requirements
  259. *
  260. * @param array $array
  261. * The roles to check.
  262. *
  263. * @return bool
  264. * true if yes, else false
  265. */
  266. public function checkGroupRole($array) {
  267. return FALSE;
  268. }
  269. /**
  270. * Get the palette of available permissions in the CMS's user-management system.
  271. *
  272. * @return array
  273. * List of permissions, keyed by symbolic name. Each item may have fields:
  274. * - title: string
  275. * - description: string
  276. *
  277. * The permission-name should correspond to the Civi notation used by
  278. * 'CRM_Core_Permission::check()'. For CMS-specific permissions, these are
  279. * translated names (eg "WordPress:list_users" or "Drupal:post comments").
  280. *
  281. * The list should include *only* CMS permissions. Exclude Civi-native permissions.
  282. *
  283. * @see \CRM_Core_Permission_Base::translatePermission()
  284. */
  285. public function getAvailablePermissions() {
  286. return [];
  287. }
  288. /**
  289. * Get all the contact emails for users that have a specific permission.
  290. *
  291. * @param string $permissionName
  292. * Name of the permission we are interested in.
  293. *
  294. * @throws CRM_Core_Exception.
  295. */
  296. public function permissionEmails($permissionName) {
  297. throw new CRM_Core_Exception("this function only works in Drupal 6 at the moment");
  298. }
  299. /**
  300. * Get all the contact emails for users that have a specific role.
  301. *
  302. * @param string $roleName
  303. * Name of the role we are interested in.
  304. *
  305. * @throws CRM_Core_Exception.
  306. */
  307. public function roleEmails($roleName) {
  308. throw new CRM_Core_Exception("this function only works in Drupal 6 at the moment");
  309. }
  310. /**
  311. * Determine whether the permission store allows us to store
  312. * a list of permissions generated dynamically (eg by
  313. * hook_civicrm_permissions.)
  314. *
  315. * @return bool
  316. */
  317. public function isModulePermissionSupported() {
  318. return FALSE;
  319. }
  320. /**
  321. * Ensure that the CMS supports all the permissions defined by CiviCRM
  322. * and its extensions. If there are stale permissions, they should be
  323. * deleted. This is useful during module upgrade when the newer module
  324. * version has removed permission that were defined in the older version.
  325. *
  326. * @param array $permissions
  327. * Same format as CRM_Core_Permission::getCorePermissions().
  328. *
  329. * @throws CRM_Core_Exception
  330. * @see CRM_Core_Permission::getCorePermissions
  331. */
  332. public function upgradePermissions($permissions) {
  333. throw new CRM_Core_Exception("Unimplemented method: CRM_Core_Permission_*::upgradePermissions");
  334. }
  335. /**
  336. * Get the permissions defined in the hook_civicrm_permission implementation
  337. * of the given module.
  338. *
  339. * Note: At time of writing, this is only used with native extension-modules, so
  340. * there's one, predictable calling convention (regardless of CMS).
  341. *
  342. * @param $module
  343. *
  344. * @return array
  345. * Array of permissions, in the same format as CRM_Core_Permission::getCorePermissions().
  346. * @see CRM_Core_Permission::getCorePermissions
  347. */
  348. public function getModulePermissions($module): array {
  349. $return_permissions = [];
  350. $fn_name = "{$module}_civicrm_permission";
  351. if (function_exists($fn_name)) {
  352. $module_permissions = [];
  353. $fn_name($module_permissions);
  354. $return_permissions = $module_permissions;
  355. }
  356. return $return_permissions;
  357. }
  358. /**
  359. * Get the permissions defined in the hook_civicrm_permission implementation
  360. * in all enabled CiviCRM module extensions.
  361. *
  362. * @param bool $descriptions
  363. *
  364. * @return array
  365. * Array of permissions, in the same format as CRM_Core_Permission::getCorePermissions().
  366. */
  367. public function getAllModulePermissions($descriptions = FALSE): array {
  368. $permissions = [];
  369. CRM_Utils_Hook::permission($permissions);
  370. if ($descriptions) {
  371. foreach ($permissions as $permission => $label) {
  372. $permissions[$permission] = (is_array($label)) ? $label : [$label];
  373. }
  374. }
  375. else {
  376. // Passing in false here is to be deprecated.
  377. foreach ($permissions as $permission => $label) {
  378. $permissions[$permission] = (is_array($label)) ? array_shift($label) : $label;
  379. }
  380. }
  381. return $permissions;
  382. }
  383. }