PageRenderTime 54ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/horde-3.3.13/lib/Horde/Kolab/Storage/Perms.php

#
PHP | 414 lines | 250 code | 37 blank | 127 comment | 65 complexity | d349e43e6df5d7e10369917cb59bbb47 MD5 | raw file
Possible License(s): LGPL-2.0
  1. <?php
  2. /**
  3. * @package Kolab_Storage
  4. *
  5. * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/Perms.php,v 1.2.2.2 2009/01/06 15:23:18 jan Exp $
  6. */
  7. /** Basic Horde Permission library. **/
  8. require_once 'Horde/Perms.php';
  9. /**
  10. * The Horde_Permission_Kolab provides a bridge between Horde
  11. * Permission handling and the IMAP permission system used on the
  12. * Kolab server.
  13. *
  14. * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/Perms.php,v 1.2.2.2 2009/01/06 15:23:18 jan Exp $
  15. *
  16. * Copyright 2006-2009 The Horde Project (http://www.horde.org/)
  17. *
  18. * See the enclosed file COPYING for license information (LGPL). If you
  19. * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
  20. *
  21. * @author Gunnar Wrobel <wrobel@pardus.de>
  22. * @package Kolab_Storage
  23. */
  24. class Horde_Permission_Kolab extends Horde_Permission {
  25. /**
  26. * The folder name.
  27. *
  28. * @var string
  29. */
  30. var $_folder;
  31. /**
  32. * A cache for the folder acl settings. The cache holds the permissions
  33. * in horde compatible format, not in the IMAP permission format.
  34. *
  35. * @var string
  36. */
  37. var $data;
  38. /**
  39. * A cache for the raw IMAP folder acl settings.
  40. *
  41. * @var string
  42. */
  43. var $acl;
  44. /**
  45. * Constructor.
  46. *
  47. * @param Kolab_Folder $folder The Kolab Folder
  48. these permissions belong to.
  49. * @param array $perms A set of initial permissions.
  50. */
  51. function Horde_Permission_Kolab(&$folder, $perms = null)
  52. {
  53. $this->setFolder($folder);
  54. if (!isset($perms)) {
  55. $result = $this->getPerm();
  56. if (is_a($result, 'PEAR_Error')) {
  57. Horde::logMessage(sprintf("Failed parsing permission information. Error was: %s",
  58. $result->getMessage()), __FILE__, __LINE__);
  59. } else {
  60. $perms = $result;
  61. }
  62. }
  63. $this->data = $perms;
  64. }
  65. /**
  66. * Returns the properties that need to be serialized.
  67. *
  68. * @return array List of serializable properties.
  69. */
  70. function __sleep()
  71. {
  72. $properties = get_object_vars($this);
  73. unset($properties['_folder']);
  74. $properties = array_keys($properties);
  75. return $properties;
  76. }
  77. /**
  78. * Sets the folder object for this permission object.
  79. *
  80. * @param string $folder Kolab Folder object.
  81. */
  82. function setFolder(&$folder)
  83. {
  84. $this->_folder = $folder;
  85. }
  86. /**
  87. * Gets one of the attributes of the object, or null if it isn't defined.
  88. *
  89. * @param string $attribute The attribute to get.
  90. *
  91. * @return mixed The value of the attribute, or null.
  92. */
  93. function get($attribute)
  94. {
  95. // This object only handles permissions. So only return these
  96. switch ($attribute) {
  97. case 'perm':
  98. return $this->data;
  99. case 'type':
  100. return 'matrix';
  101. default:
  102. // User requested something other than permissions: return null
  103. return null;
  104. }
  105. }
  106. /**
  107. * Gets the current permission of the folder and stores the values in the
  108. * cache.
  109. *
  110. * @return array|PEAR_Error The data array representing the permissions.
  111. */
  112. function getPerm()
  113. {
  114. $acl = $this->_folder->getACL();
  115. if (is_a($acl, 'PEAR_Error')) {
  116. Horde::logMessage($acl, __FILE__, __LINE__);
  117. return array();
  118. }
  119. if (empty($acl)) {
  120. return array();
  121. }
  122. $this->acl = &$acl;
  123. // Loop through the returned users
  124. $data = array();
  125. foreach ($acl as $user => $rights) {
  126. // Convert the user rights to horde format
  127. $result = 0;
  128. for ($i = 0, $j = strlen($rights); $i < $j; $i++) {
  129. switch ($rights[$i]) {
  130. case 'l':
  131. $result |= PERMS_SHOW;
  132. break;
  133. case 'r':
  134. $result |= PERMS_READ;
  135. break;
  136. case 'i':
  137. $result |= PERMS_EDIT;
  138. break;
  139. case 'd':
  140. $result |= PERMS_DELETE;
  141. break;
  142. }
  143. }
  144. // Check for special users
  145. $name = '';
  146. switch ($user) {
  147. case 'anyone':
  148. $name = 'default';
  149. break;
  150. case 'anonymous':
  151. $name = 'guest';
  152. break;
  153. }
  154. // Did we have a special user?
  155. if ($name) {
  156. // Store the converted acl in the cache
  157. $data[$name] = $result;
  158. continue;
  159. }
  160. // Is it a group?
  161. if (substr($user, 0, 6) == 'group:') {
  162. if (!isset($groups)) {
  163. require_once 'Horde/Group.php';
  164. $groups = &Group::singleton();
  165. }
  166. $group_id = $groups->getGroupId(substr($user, 6));
  167. if (!is_a($group_id, 'PEAR_Error')) {
  168. // Store the converted acl in the cache
  169. $data['groups'][$group_id] = $result;
  170. }
  171. continue;
  172. }
  173. // Standard user
  174. // Store the converted acl in the cache
  175. $data['users'][$user] = $result;
  176. }
  177. return $data;
  178. }
  179. /**
  180. * Saves the current permission values from the cache to the IMAP folder.
  181. *
  182. * @return boolean|PEAR_Error True on success, false if there is
  183. * nothing to save.
  184. */
  185. function save()
  186. {
  187. if (!isset($this->data)) {
  188. return false;
  189. }
  190. // FIXME: If somebody else accessed the folder before us, we will overwrite
  191. // the change here.
  192. $current = $this->getPerm();
  193. foreach ($this->data as $user => $user_perms) {
  194. if (is_array($user_perms)) {
  195. foreach ($user_perms as $userentry => $perms) {
  196. if ($user == 'groups') {
  197. if (!isset($groups)) {
  198. require_once 'Horde/Group.php';
  199. $groups = &Group::singleton();
  200. }
  201. // Convert group id back to name
  202. $group_name = $groups->getGroupName($userentry);
  203. if (is_a($group_name, 'PEAR_Error')) {
  204. return $group_name;
  205. }
  206. $name = 'group:' . $group_name;
  207. } else if ($user == 'users') {
  208. $name = $userentry;
  209. } else {
  210. continue;
  211. }
  212. $result = $this->savePermission($name, $perms);
  213. if (is_a($result, 'PEAR_Error')) {
  214. return $result;
  215. }
  216. unset($current[$user][$userentry]);
  217. }
  218. } else {
  219. if ($user == 'default') {
  220. $name = 'anyone';
  221. } else if ($user == 'guest') {
  222. $name = 'anonymous';
  223. } else {
  224. continue;
  225. }
  226. $result = $this->savePermission($name, $user_perms);
  227. if (is_a($result, 'PEAR_Error')) {
  228. return $result;
  229. }
  230. unset($current[$user]);
  231. }
  232. }
  233. // Delete ACLs that have been removed
  234. foreach ($current as $user => $user_perms) {
  235. if (is_array($user_perms)) {
  236. foreach ($user_perms as $userentry => $perms) {
  237. if ($user == 'groups') {
  238. if (!isset($groups)) {
  239. require_once 'Horde/Group.php';
  240. $groups = &Group::singleton();
  241. }
  242. // Convert group id back to name
  243. $group_name = $groups->getGroupName($userentry);
  244. if (is_a($group_name, 'PEAR_Error')) {
  245. return $group_name;
  246. }
  247. $name = 'group:' . $group_name;
  248. } else {
  249. $name = $userentry;
  250. }
  251. $result = $this->_folder->deleteACL($name);
  252. if (is_a($result, 'PEAR_Error')) {
  253. return $result;
  254. }
  255. }
  256. } else {
  257. if ($user == 'default') {
  258. $name = 'anyone';
  259. } else if ($user == 'guest') {
  260. $name = 'anonymous';
  261. } else {
  262. continue;
  263. }
  264. $result = $this->_folder->deleteACL($name);
  265. if (is_a($result, 'PEAR_Error')) {
  266. return $result;
  267. }
  268. }
  269. }
  270. // Load the permission from the folder again
  271. $this->data = $this->getPerm();
  272. return true;
  273. }
  274. /**
  275. * Saves the specified permission values for the given user on the
  276. * IMAP folder.
  277. *
  278. * @return boolean|PEAR_Error True on success.
  279. */
  280. function savePermission($user, $perms)
  281. {
  282. // Convert the horde permission style to IMAP permissions
  283. $result = $user == $this->_folder->getOwner() ? 'a' : '';
  284. if ($perms & PERMS_SHOW) {
  285. $result .= 'l';
  286. }
  287. if ($perms & PERMS_READ) {
  288. $result .= 'r';
  289. }
  290. if ($perms & PERMS_EDIT) {
  291. $result .= 'iswc';
  292. }
  293. if ($perms & PERMS_DELETE) {
  294. $result .= 'd';
  295. }
  296. $result = $this->_folder->setACL($user, $result);
  297. if (is_a($result, 'PEAR_Error')) {
  298. return $result;
  299. }
  300. return true;
  301. }
  302. /**
  303. * Finds out what rights the given user has to this object.
  304. *
  305. * @param string $user The user to check for. Defaults to the current
  306. * user.
  307. * @param string $creator The user who created the object.
  308. *
  309. * @return mixed A bitmask of permissions, a permission value, or
  310. * an array of permission values the user has,
  311. * depending on the permission type and whether the
  312. * permission value is ambiguous. False if there is
  313. * no such permsission.
  314. */
  315. function getPermissions($user = null, $creator = null)
  316. {
  317. if ($user === null) {
  318. $user = Auth::getAuth();
  319. }
  320. // If $creator was specified, check creator permissions.
  321. if ($creator !== null) {
  322. // If the user is the creator see if there are creator
  323. // permissions.
  324. if (strlen($user) && $user === $creator &&
  325. ($perms = $this->getCreatorPermissions()) !== null) {
  326. return $perms;
  327. }
  328. }
  329. // Check user-level permissions.
  330. $userperms = $this->getUserPermissions();
  331. if (isset($userperms[$user])) {
  332. return $userperms[$user];
  333. }
  334. // If no user permissions are found, try group permissions.
  335. $groupperms = $this->getGroupPermissions();
  336. if (!empty($groupperms)) {
  337. require_once 'Horde/Group.php';
  338. $groups = &Group::singleton();
  339. $composite_perm = null;
  340. foreach ($this->data['groups'] as $group => $perm) {
  341. $result = $groups->userIsInGroup($user, $group);
  342. if (is_a($result, 'PEAR_Error')) {
  343. return $result;
  344. }
  345. if ($result) {
  346. if ($composite_perm === null) {
  347. $composite_perm = 0;
  348. }
  349. $composite_perm |= $perm;
  350. }
  351. }
  352. if ($composite_perm !== null) {
  353. return $composite_perm;
  354. }
  355. }
  356. // If there are default permissions, return them.
  357. if (($perms = $this->getDefaultPermissions()) !== null) {
  358. return $perms;
  359. }
  360. // Otherwise, deny all permissions to the object.
  361. return false;
  362. }
  363. /**
  364. * Finds out if the user has the specified rights to the given object.
  365. *
  366. * @param string $user The user to check for.
  367. * @param integer $perm The permission level that needs to be checked
  368. * for.
  369. * @param string $creator The creator of the shared object.
  370. *
  371. * @return boolean True if the user has the specified permissions.
  372. */
  373. function hasPermission($user, $perm, $creator = null)
  374. {
  375. return ($this->getPermissions($user, $creator) & $perm);
  376. }
  377. }