PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/sites/all/modules/contrib/civicrm/CRM/Core/Permission/Joomla.php

https://gitlab.com/virtualrealms/d7civicrm
PHP | 215 lines | 95 code | 31 blank | 89 comment | 14 complexity | a3a1b333fbe83602ec721f1e0cb1bf98 MD5 | raw file
  1. <?php
  2. /*
  3. +--------------------------------------------------------------------+
  4. | CiviCRM version 5 |
  5. +--------------------------------------------------------------------+
  6. | Copyright CiviCRM LLC (c) 2004-2019 |
  7. +--------------------------------------------------------------------+
  8. | This file is a part of CiviCRM. |
  9. | |
  10. | CiviCRM is free software; you can copy, modify, and distribute it |
  11. | under the terms of the GNU Affero General Public License |
  12. | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
  13. | |
  14. | CiviCRM is distributed in the hope that it will be useful, but |
  15. | WITHOUT ANY WARRANTY; without even the implied warranty of |
  16. | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
  17. | See the GNU Affero General Public License for more details. |
  18. | |
  19. | You should have received a copy of the GNU Affero General Public |
  20. | License and the CiviCRM Licensing Exception along |
  21. | with this program; if not, contact CiviCRM LLC |
  22. | at info[AT]civicrm[DOT]org. If you have questions about the |
  23. | GNU Affero General Public License or the licensing of CiviCRM, |
  24. | see the CiviCRM license FAQ at http://civicrm.org/licensing |
  25. +--------------------------------------------------------------------+
  26. */
  27. /**
  28. *
  29. * @package CRM
  30. * @copyright CiviCRM LLC (c) 2004-2019
  31. * $Id$
  32. *
  33. */
  34. /**
  35. *
  36. */
  37. class CRM_Core_Permission_Joomla extends CRM_Core_Permission_Base {
  38. /**
  39. * Given a permission string, check for access requirements
  40. *
  41. * @param string $str
  42. * The permission to check.
  43. * @param int $userId
  44. *
  45. * @return bool
  46. * true if yes, else false
  47. */
  48. public function check($str, $userId = NULL) {
  49. $config = CRM_Core_Config::singleton();
  50. // JFactory::getUser does strict type checking, so convert falesy values to NULL
  51. if (!$userId) {
  52. $userId = NULL;
  53. }
  54. $translated = $this->translateJoomlaPermission($str);
  55. if ($translated === CRM_Core_Permission::ALWAYS_DENY_PERMISSION) {
  56. return FALSE;
  57. }
  58. if ($translated === CRM_Core_Permission::ALWAYS_ALLOW_PERMISSION) {
  59. return TRUE;
  60. }
  61. // ensure that we are running in a joomla context
  62. // we've not yet figured out how to bootstrap joomla, so we should
  63. // not execute hooks if joomla is not loaded
  64. if (defined('_JEXEC')) {
  65. $user = JFactory::getUser($userId);
  66. $api_key = CRM_Utils_Request::retrieve('api_key', 'String', $store, FALSE, NULL, 'REQUEST');
  67. // If we are coming from REST we don't have a user but we do have the api_key for a user.
  68. if ($user->id === 0 && !is_null($api_key)) {
  69. // This is a codeblock copied from /Civicrm/Utils/REST
  70. $uid = NULL;
  71. if (!$uid) {
  72. $store = NULL;
  73. $contact_id = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $api_key, 'id', 'api_key');
  74. if ($contact_id) {
  75. $uid = CRM_Core_BAO_UFMatch::getUFId($contact_id);
  76. }
  77. $user = JFactory::getUser($uid);
  78. }
  79. }
  80. return $user->authorise($translated[0], $translated[1]);
  81. }
  82. else {
  83. return FALSE;
  84. }
  85. }
  86. public function isModulePermissionSupported() {
  87. return TRUE;
  88. }
  89. /**
  90. * @param $perm
  91. *
  92. * @internal param string $name e.g. "administer CiviCRM", "cms:access user record", "Drupal:administer content", "Joomla:example.action:com_some_asset"
  93. * @return ALWAYS_DENY_PERMISSION|ALWAYS_ALLOW_PERMISSION|array(0 => $joomlaAction, 1 => $joomlaAsset)
  94. */
  95. public function translateJoomlaPermission($perm) {
  96. if ($perm === CRM_Core_Permission::ALWAYS_DENY_PERMISSION || $perm === CRM_Core_Permission::ALWAYS_ALLOW_PERMISSION) {
  97. return $perm;
  98. }
  99. list ($civiPrefix, $name) = CRM_Utils_String::parsePrefix(':', $perm, NULL);
  100. switch ($civiPrefix) {
  101. case 'Joomla':
  102. return explode(':', $name);
  103. case 'cms':
  104. // FIXME: This needn't be DENY, but we don't currently have any translations.
  105. return CRM_Core_Permission::ALWAYS_DENY_PERMISSION;
  106. case NULL:
  107. return ['civicrm.' . CRM_Utils_String::munge(strtolower($name)), 'com_civicrm'];
  108. default:
  109. return CRM_Core_Permission::ALWAYS_DENY_PERMISSION;
  110. }
  111. }
  112. /**
  113. * Given a roles array, check for access requirements
  114. *
  115. * @param array $array
  116. * The roles to check.
  117. *
  118. * @return bool
  119. * true if yes, else false
  120. */
  121. public function checkGroupRole($array) {
  122. return FALSE;
  123. }
  124. /**
  125. * @inheritDoc
  126. */
  127. public function upgradePermissions($permissions) {
  128. $translatedPerms = [];
  129. // Flipping the $permissions array gives us just the raw names of the
  130. // permissions. The descriptions, etc., are irrelevant for the purposes of
  131. // this method.
  132. foreach (array_flip($permissions) as $perm) {
  133. $translated = $this->translateJoomlaPermission($perm);
  134. $translatedPerms[] = $translated[0];
  135. }
  136. $associations = $this->getUserGroupPermsAssociations();
  137. $cmsPermsHaveGoneStale = FALSE;
  138. foreach (array_keys(get_object_vars($associations)) as $permName) {
  139. if (!in_array($permName, $translatedPerms)) {
  140. unset($associations->$permName);
  141. $cmsPermsHaveGoneStale = TRUE;
  142. }
  143. }
  144. if ($cmsPermsHaveGoneStale) {
  145. $this->updateGroupPermsAssociations($associations);
  146. }
  147. }
  148. /**
  149. * Fetches the associations between user groups and CiviCRM permissions.
  150. *
  151. * @see https://docs.joomla.org/Selecting_data_using_JDatabase
  152. * @return object
  153. * Properties of the object are Joomla-fied permission names.
  154. */
  155. private function getUserGroupPermsAssociations() {
  156. $db = JFactory::getDbo();
  157. $query = $db->getQuery(TRUE);
  158. $query
  159. ->select($db->quoteName('rules'))
  160. ->from($db->quoteName('#__assets'))
  161. ->where($db->quoteName('name') . ' = ' . $db->quote('com_civicrm'));
  162. $db->setQuery($query);
  163. // Joomla gotcha: loadObject returns NULL in the case of no matches.
  164. $result = $db->loadObject();
  165. return $result ? json_decode($result->rules) : (object) [];
  166. }
  167. /**
  168. * Writes user-group/permissions associations back to Joomla.
  169. *
  170. * @see https://docs.joomla.org/Inserting,_Updating_and_Removing_data_using_JDatabase
  171. * @param object $associations
  172. * Same format as the return of
  173. * CRM_Core_Permission_Joomla->getUserGroupPermsAssociations().
  174. */
  175. private function updateGroupPermsAssociations($associations) {
  176. $db = JFactory::getDbo();
  177. $query = $db->getQuery(TRUE);
  178. $query
  179. ->update($db->quoteName('#__assets'))
  180. ->set($db->quoteName('rules') . ' = ' . $db->quote(json_encode($associations)))
  181. ->where($db->quoteName('name') . ' = ' . $db->quote('com_civicrm'));
  182. $db->setQuery($query)->execute();
  183. }
  184. }