9 * This source file is subject to the new BSD license that is bundled
10 * with this package in the file LICENSE.
11 * It is also available through the world-wide-web at this URL:
12 * http://phergie.org/license
15 * @package Phergie_Plugin_Acl
16 * @author Phergie Development Team <team@phergie.org>
17 * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
18 * @license http://phergie.org/license New BSD License
19 * @link http://pear.phergie.org/package/Phergie_Plugin_Acl
23 * Provides an access control system to limit reponses to events based on
24 * the users who originate them.
26 * Configuration settings:
27 * acl.whitelist - mapping of user hostmask patterns (optionally by host) to
28 * plugins and methods where those plugins and methods will
29 * only be accessible to those users (i.e. and inaccessible
31 * acl.blacklist - mapping of user hostmasks (optionally by host) to plugins
32 * and methods where where those plugins and methods will be
33 * inaccessible to those users but accessible to other users
34 * acl.ops - TRUE to automatically give access to whitelisted plugins
35 * and methods to users with ops for events they initiate in
36 * channels where they have ops
38 * The whitelist and blacklist settings are formatted like so:
40 * 'acl.whitelist' => array(
41 * 'hostname1' => array(
42 * 'pattern1' => array(
54 * The hostname array dimension is optional; if not used, rules will be
55 * applied across all connections. The pattern is a user hostmask pattern
56 * where asterisks (*) are used for wildcards. Plugins and methods do not
57 * need to be set to empty arrays if they are not used; simply exclude them.
60 * @package Phergie_Plugin_Acl
61 * @author Phergie Development Team <team@phergie.org>
62 * @license http://phergie.org/license New BSD License
63 * @link http://pear.phergie.org/package/Phergie_Plugin_Acl
64 * @uses Phergie_Plugin_UserInfo pear.phergie.org
66 class Phergie_Plugin_Acl extends Phergie_Plugin_Abstract
69 * Checks for permission settings and removes the plugin if none are set.
73 public function onLoad()
75 $this->plugins->getPlugin('UserInfo');
77 if (!$this->getConfig('acl.blacklist')
78 && !$this->getConfig('acl.whitelist')
80 $this->plugins->removePlugin($this);
85 * Applies a set of rules to a plugin handler iterator.
87 * @param Phergie_Plugin_Iterator $iterator Iterator to receive rules
88 * @param array $rules Associate array containing
89 * either a 'plugins' key pointing to an array containing plugin
90 * short names to filter, a 'methods' key pointing to an array
91 * containing method names to filter, or both
95 protected function applyRules(Phergie_Plugin_Iterator $iterator, array $rules)
97 if (!empty($rules['plugins'])) {
98 $iterator->addPluginFilter($rules['plugins']);
100 if (!empty($rules['methods'])) {
101 $iterator->addMethodFilter($rules['methods']);
106 * Checks permission settings and short-circuits event processing for
111 public function preEvent()
113 // Ignore server responses
114 if ($this->event instanceof Phergie_Event_Response) {
118 // Ignore server-initiated events
119 if (!$this->event->isFromUser()) {
123 // Get the iterator used to filter plugins when processing events
124 $iterator = $this->plugins->getIterator();
126 // Get configuration setting values
127 $whitelist = $this->getConfig('acl.whitelist', array());
128 $blacklist = $this->getConfig('acl.blacklist', array());
129 $ops = $this->getConfig('acl.ops', false);
131 // Support host-specific lists
132 $host = $this->connection->getHost();
133 foreach (array('whitelist', 'blacklist') as $var) {
134 foreach ($$var as $pattern => $rules) {
135 $regex = '/^' . str_replace('*', '.*', $pattern) . '$/i';
136 if (preg_match($regex, $host)) {
137 ${$var} = ${$var}[$pattern];
143 // Get information on the user initiating the current event
144 $hostmask = $this->event->getHostmask();
146 && $this->event->isInChannel()
147 && $this->plugins->userInfo->isOp(
148 $this->event->getNick(),
149 $this->event->getSource()
152 // Filter whitelisted commands if the user is not on the whitelist
154 $whitelisted = false;
155 foreach ($whitelist as $pattern => $rules) {
156 if ($hostmask->matches($pattern)) {
161 foreach ($whitelist as $pattern => $rules) {
162 $this->applyRules($iterator, $rules);
167 // Filter blacklisted commands if the user is on the blacklist
168 $blacklisted = false;
169 foreach ($blacklist as $pattern => $rules) {
170 if ($hostmask->matches($pattern)) {
171 $this->applyRules($iterator, $rules);
178 * Clears filters on the plugin handler iterator.
182 public function postDispatch()
184 $this->plugins->getIterator()->clearFilters();