1: <?php
2: /**
3: * The Horde_Core_Perms class provides information about internal Horde
4: * elements that can be managed through the Horde_Perms system.
5: *
6: * Copyright 2001-2012 Horde LLC (http://www.horde.org/)
7: *
8: * See the enclosed file COPYING for license information (LGPL). If you
9: * did not receive this file, see http://www.horde.org/licenses/lgpl21.
10: *
11: * @author Chuck Hagenbuch <chuck@horde.org>
12: * @author Jan Schneider <jan@horde.org>
13: * @category Horde
14: * @package Core
15: */
16: class Horde_Core_Perms
17: {
18: /**
19: * A registry instance.
20: *
21: * @var Horde_Registry
22: */
23: protected $_registry;
24:
25: /**
26: * A permissions instance.
27: *
28: * @var Horde_Perms_Base
29: */
30: protected $_perms;
31:
32: /**
33: * Caches information about application permissions.
34: *
35: * @var array
36: */
37: protected $_appPerms;
38:
39: /**
40: * Constructor.
41: *
42: * @params Horde_Registry $registry
43: * @params Horde_Perms_Base $perms
44: */
45: public function __construct(Horde_Registry $registry,
46: Horde_Perms_Base $perms)
47: {
48: $this->_registry = $registry;
49: $this->_perms = $perms;
50: }
51:
52: /**
53: * Returns the available permissions for a given level.
54: *
55: * @param string $name The permission's name.
56: *
57: * @return array An array of available permissions and their titles or
58: * false if not sub permissions exist for this level.
59: * @throws Horde_Perms_Exception
60: */
61: public function getAvailable($name)
62: {
63: if ($name == Horde_Perms::ROOT) {
64: $name = '';
65: }
66:
67: if (empty($name)) {
68: /* No name passed, so top level permissions are requested. These
69: * can only be applications. */
70: $apps = $this->_registry->listApps(array('notoolbar', 'active', 'hidden'), true);
71: foreach (array_keys($apps) as $app) {
72: $apps[$app] = $this->_registry->get('name', $app) . ' (' . $app . ')';
73: }
74: asort($apps);
75: return $apps;
76: }
77:
78: /* Name has been passed, explode the name to get all the levels in
79: * permission being requisted, with the app as the first level. */
80: $levels = explode(':', $name);
81:
82: /* First level is always app. */
83: $app = $levels[0];
84:
85: /* Call the app's permission function to return the permissions
86: * specific to this app. */
87: $perms = $this->getApplicationPermissions($app);
88: if (!count($perms)) {
89: return false;
90: }
91:
92: /* Get the part of the app's permissions based on the permission
93: * name requested. */
94: $children = Horde_Array::getElement($perms['tree'], $levels);
95: if (($children === false) ||
96: !is_array($children) ||
97: !count($children)) {
98: /* No array of children available for this permission name. */
99: return false;
100: }
101:
102: $perms_list = array();
103: foreach ($children as $perm_key => $perm_val) {
104: $perms_list[$perm_key] = $perms['title'][$name . ':' . $perm_key];
105: }
106:
107: return $perms_list;
108: }
109:
110: /**
111: * Given a permission name, returns the title for that permission by
112: * looking it up in the applications's permission api.
113: *
114: * @param string $name The permissions's name.
115: *
116: * @return string The title for the permission.
117: */
118: public function getTitle($name)
119: {
120: if ($name === Horde_Perms::ROOT) {
121: return Horde_Core_Translation::t("All Permissions");
122: }
123:
124: $levels = explode(':', $name);
125: if (count($levels) == 1) {
126: return $this->_registry->get('name', $name) . ' (' . $name . ')';
127: }
128: $perm = array_pop($levels);
129:
130: /* First level is always app. */
131: $app = $levels[0];
132:
133: $app_perms = $this->getApplicationPermissions($app);
134:
135: return isset($app_perms['title'][$name])
136: ? $app_perms['title'][$name] . ' (' . $this->_perms->getShortName($name) . ')'
137: : $this->_perms->getShortName($name);
138: }
139:
140: /**
141: * Given a permission name, returns the type for that permission.
142: *
143: * @param string $name The permissions's name.
144: *
145: * @return string The type for the permission.
146: */
147: public function getType($name)
148: {
149: $type = 'matrix';
150: if ($pos = strpos($name, ':')) {
151: try {
152: $info = $this->getApplicationPermissions(substr($name, 0, $pos));
153: if (isset($info['type']) && isset($info['type'][$name])) {
154: $type = $info['type'][$name];
155: }
156: } catch (Horde_Perms_Exception $e) {}
157: }
158: return $type;
159: }
160:
161: /**
162: * Given a permission name, returns the parameters for that permission.
163: *
164: * @param string $name The permissions's name.
165: *
166: * @return array The paramters for the permission.
167: */
168: public function getParams($name)
169: {
170: $params = null;
171: if ($pos = strpos($name, ':')) {
172: try {
173: $info = $this->getApplicationPermissions(substr($name, 0, $pos));
174: if (isset($info['params']) && isset($info['params'][$name])) {
175: $params = $info['params'][$name];
176: }
177: } catch (Horde_Perms_Exception $e) {}
178: }
179: return $params;
180: }
181:
182: /**
183: * Returns a new permissions object.
184: *
185: * This must be used instead of Horde_Perms_Base::newPermission() because
186: * it works with application-specific permissions.
187: *
188: * @param string $name The permission's name.
189: *
190: * @return Horde_Perms_Permission A new permissions object.
191: */
192: public function newPermission($name)
193: {
194: return $this->_perms->newPermission($name,
195: $this->getType($name),
196: $this->getParams($name));
197: }
198:
199: /**
200: * Returns information about permissions implemented by an application.
201: *
202: * @param string $app An application name.
203: *
204: * @return array Hash with permissions information.
205: */
206: public function getApplicationPermissions($app)
207: {
208: if (!isset($this->_appPerms[$app])) {
209: try {
210: $app_perms = $this->_registry->callAppMethod($app, 'perms');
211: } catch (Horde_Exception $e) {
212: $app_perms = array();
213: }
214:
215: if (empty($app_perms)) {
216: $perms = array();
217: } else {
218: $perms = array(
219: 'title' => array(),
220: 'tree' => array(
221: $app => array()
222: ),
223: 'type' => array()
224: );
225:
226: foreach ($app_perms as $key => $val) {
227: $ptr = &$perms['tree'][$app];
228:
229: foreach (explode(':', $key) as $kval) {
230: if (!isset($ptr[$kval])) {
231: $ptr[$kval] = false;
232: }
233: $ptr = &$ptr[$kval];
234: }
235: if (isset($val['title'])) {
236: $perms['title'][$app . ':' . $key] = $val['title'];
237: }
238: if (isset($val['type'])) {
239: $perms['type'][$app . ':' . $key] = $val['type'];
240: }
241: }
242: }
243:
244: $this->_appPerms[$app] = $perms;
245: }
246:
247: return $this->_appPerms[$app];
248: }
249:
250: /**
251: * Finds out if the user has the specified rights to the given object,
252: * specific to a certain application.
253: *
254: * @param string $permission The permission to check.
255: * @param array $opts Additional options:
256: * <pre>
257: * 'app' - (string) The app to check.
258: * DEFAULT: The current pushed app.
259: * 'opts' - (array) Additional options to pass to the app function.
260: * DEFAULT: None
261: * </pre>
262: *
263: * @return mixed The specified permissions.
264: */
265: public function hasAppPermission($permission, $opts = array())
266: {
267: $app = isset($opts['app'])
268: ? $opts['app']
269: : $this->_registry->getApp();
270:
271: if ($this->_perms->exists($app . ':' . $permission)) {
272: $perms = $this->_perms->getPermissions($app . ':' . $permission, $this->_registry->getAuth());
273: if ($perms === false) {
274: return false;
275: }
276:
277: $args = array(
278: $permission,
279: $perms,
280: isset($opts['opts']) ? $opts['opts'] : array()
281: );
282:
283: try {
284: return $this->_registry->callAppMethod($app, 'hasPermission', array('args' => $args));
285: } catch (Horde_Exception $e) {}
286: }
287:
288: return true;
289: }
290: }
291: