]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/Irc/extlib/phergie/Phergie/Plugin/Acl.php
Merge branch 'master' into social-master
[quix0rs-gnu-social.git] / plugins / Irc / extlib / phergie / Phergie / Plugin / Acl.php
1 <?php
2 /**
3  * Phergie
4  *
5  * PHP version 5
6  *
7  * LICENSE
8  *
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
13  *
14  * @category  Phergie
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
20  */
21
22 /**
23  * Provides an access control system to limit reponses to events based on
24  * the users who originate them.
25  *
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
30  *                 to other users)
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
37  *
38  * The whitelist and blacklist settings are formatted like so:
39  * <code>
40  * 'acl.whitelist' => array(
41  *     'hostname1' => array(
42  *         'pattern1' => array(
43  *             'plugins' => array(
44  *                 'ShortPluginName'
45  *             ),
46  *             'methods' => array(
47  *                 'methodName'
48  *             )
49  *         ),
50  *     )
51  * ),
52  * </code>
53  *
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.
58  *
59  * @category Phergie
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
65  */
66 class Phergie_Plugin_Acl extends Phergie_Plugin_Abstract
67 {
68     /**
69      * Checks for permission settings and removes the plugin if none are set.
70      *
71      * @return void
72      */
73     public function onLoad()
74     {
75         $this->plugins->getPlugin('UserInfo');
76
77         if (!$this->getConfig('acl.blacklist')
78             && !$this->getConfig('acl.whitelist')
79         ) {
80             $this->plugins->removePlugin($this);
81         }
82     }
83
84     /**
85      * Applies a set of rules to a plugin handler iterator.
86      *
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
92      *
93      * @return void
94      */
95     protected function applyRules(Phergie_Plugin_Iterator $iterator, array $rules)
96     {
97         if (!empty($rules['plugins'])) {
98             $iterator->addPluginFilter($rules['plugins']);
99         }
100         if (!empty($rules['methods'])) {
101             $iterator->addMethodFilter($rules['methods']);
102         }
103     }
104
105     /**
106      * Checks permission settings and short-circuits event processing for
107      * blacklisted users.
108      *
109      * @return void
110      */
111     public function preEvent()
112     {
113         // Ignore server responses
114         if ($this->event instanceof Phergie_Event_Response) {
115             return;
116         }
117
118         // Ignore server-initiated events
119         if (!$this->event->isFromUser()) {
120             return;
121         }
122
123         // Get the iterator used to filter plugins when processing events
124         $iterator = $this->plugins->getIterator();
125
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);
130
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];
138                     break;
139                 }
140             }
141         }
142
143         // Get information on the user initiating the current event
144         $hostmask = $this->event->getHostmask();
145         $isOp = $ops
146               && $this->event->isInChannel()
147               && $this->plugins->userInfo->isOp(
148                 $this->event->getNick(),
149                 $this->event->getSource()
150               );
151
152         // Filter whitelisted commands if the user is not on the whitelist
153         if (!$isOp) {
154             $whitelisted = false;
155             foreach ($whitelist as $pattern => $rules) {
156                 if ($hostmask->matches($pattern)) {
157                     $whitelisted = true;
158                 }
159             }
160             if (!$whitelisted) {
161                 foreach ($whitelist as $pattern => $rules) {
162                     $this->applyRules($iterator, $rules);
163                 }
164             }
165         }
166
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);
172                 break;
173             }
174         }
175     }
176
177     /**
178      * Clears filters on the plugin handler iterator.
179      *
180      * @return void
181      */
182     public function postDispatch()
183     {
184         $this->plugins->getIterator()->clearFilters();
185     }
186 }