]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - plugins/Irc/extlib/phergie/Phergie/Plugin/Acl.php
Merged in Phergie changes
[quix0rs-gnu-social.git] / plugins / Irc / extlib / phergie / Phergie / Plugin / Acl.php
index 9738df60e052b0651f2477560b2c12646ed20135..e209e32e142ee8cb729707a7b62af90a0c793dbb 100755 (executable)
@@ -1,6 +1,6 @@
 <?php
 /**
- * Phergie 
+ * Phergie
  *
  * PHP version 5
  *
@@ -11,7 +11,7 @@
  * It is also available through the world-wide-web at this URL:
  * http://phergie.org/license
  *
- * @category  Phergie 
+ * @category  Phergie
  * @package   Phergie_Plugin_Acl
  * @author    Phergie Development Team <team@phergie.org>
  * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
  */
 
 /**
- * Provides an access control system to limit reponses to events based on 
+ * Provides an access control system to limit reponses to events based on
  * the users who originate them.
  *
- * @category Phergie 
+ * Configuration settings:
+ * acl.whitelist - mapping of user hostmask patterns (optionally by host) to
+ *                 plugins and methods where those plugins and methods will
+ *                 only be accessible to those users (i.e. and inaccessible
+ *                 to other users)
+ * acl.blacklist - mapping of user hostmasks (optionally by host) to plugins
+ *                 and methods where where those plugins and methods will be
+ *                 inaccessible to those users but accessible to other users
+ * acl.ops       - TRUE to automatically give access to whitelisted plugins
+ *                 and methods to users with ops for events they initiate in
+ *                 channels where they have ops
+ *
+ * The whitelist and blacklist settings are formatted like so:
+ * <code>
+ * 'acl.whitelist' => array(
+ *     'hostname1' => array(
+ *         'pattern1' => array(
+ *             'plugins' => array(
+ *                 'ShortPluginName'
+ *             ),
+ *             'methods' => array(
+ *                 'methodName'
+ *             )
+ *         ),
+ *     )
+ * ),
+ * </code>
+ *
+ * The hostname array dimension is optional; if not used, rules will be
+ * applied across all connections. The pattern is a user hostmask pattern
+ * where asterisks (*) are used for wildcards. Plugins and methods do not
+ * need to be set to empty arrays if they are not used; simply exclude them.
+ *
+ * @category Phergie
  * @package  Phergie_Plugin_Acl
  * @author   Phergie Development Team <team@phergie.org>
  * @license  http://phergie.org/license New BSD License
  * @link     http://pear.phergie.org/package/Phergie_Plugin_Acl
+ * @uses     Phergie_Plugin_UserInfo pear.phergie.org
  */
 class Phergie_Plugin_Acl extends Phergie_Plugin_Abstract
 {
@@ -38,6 +72,8 @@ class Phergie_Plugin_Acl extends Phergie_Plugin_Abstract
      */
     public function onLoad()
     {
+        $this->plugins->getPlugin('UserInfo');
+
         if (!$this->getConfig('acl.blacklist')
             && !$this->getConfig('acl.whitelist')
         ) {
@@ -46,47 +82,105 @@ class Phergie_Plugin_Acl extends Phergie_Plugin_Abstract
     }
 
     /**
-     * Checks permission settings and short-circuits event processing for 
+     * Applies a set of rules to a plugin handler iterator.
+     *
+     * @param Phergie_Plugin_Iterator $iterator Iterator to receive rules
+     * @param array                   $rules    Associate array containing
+     *        either a 'plugins' key pointing to an array containing plugin
+     *        short names to filter, a 'methods' key pointing to an array
+     *        containing method names to filter, or both
+     *
+     * @return void
+     */
+    protected function applyRules(Phergie_Plugin_Iterator $iterator, array $rules)
+    {
+        if (!empty($rules['plugins'])) {
+            $iterator->addPluginFilter($rules['plugins']);
+        }
+        if (!empty($rules['methods'])) {
+            $iterator->addMethodFilter($rules['methods']);
+        }
+    }
+
+    /**
+     * Checks permission settings and short-circuits event processing for
      * blacklisted users.
      *
-     * @return bool FALSE to short-circuit event processing if the user is 
-     *         blacklisted, TRUE otherwise
+     * @return void
      */
     public function preEvent()
     {
         // Ignore server responses
         if ($this->event instanceof Phergie_Event_Response) {
-            return true;
+            return;
         }
 
         // Ignore server-initiated events
         if (!$this->event->isFromUser()) {
-            return true;
+            return;
         }
 
-        // Determine whether a whitelist or blacklist is being used
-        $list = $this->getConfig('acl.whitelist');
-        $matches = true;
-        if (!$list) {
-            $list = $this->getConfig('acl.blacklist');
-            $matches = false;
-        }
+        // Get the iterator used to filter plugins when processing events
+        $iterator = $this->plugins->getIterator();
+
+        // Get configuration setting values
+        $whitelist = $this->getConfig('acl.whitelist', array());
+        $blacklist = $this->getConfig('acl.blacklist', array());
+        $ops = $this->getConfig('acl.ops', false);
 
-        // Support host-specific lists 
+        // Support host-specific lists
         $host = $this->connection->getHost();
-        if (isset($list[$host])) {
-            $list = $list[$host];
+        foreach (array('whitelist', 'blacklist') as $var) {
+            foreach ($$var as $pattern => $rules) {
+                $regex = '/^' . str_replace('*', '.*', $pattern) . '$/i';
+                if (preg_match($regex, $host)) {
+                    ${$var} = ${$var}[$pattern];
+                    break;
+                }
+            }
         }
 
-        // Short-circuit event processing if appropriate 
+        // Get information on the user initiating the current event
         $hostmask = $this->event->getHostmask();
-        foreach ($list as $pattern) {
+        $isOp = $ops
+              && $this->event->isInChannel()
+              && $this->plugins->userInfo->isOp(
+                $this->event->getNick(),
+                $this->event->getSource()
+              );
+
+        // Filter whitelisted commands if the user is not on the whitelist
+        if (!$isOp) {
+            $whitelisted = false;
+            foreach ($whitelist as $pattern => $rules) {
+                if ($hostmask->matches($pattern)) {
+                    $whitelisted = true;
+                }
+            }
+            if (!$whitelisted) {
+                foreach ($whitelist as $pattern => $rules) {
+                    $this->applyRules($iterator, $rules);
+                }
+            }
+        }
+
+        // Filter blacklisted commands if the user is on the blacklist
+        $blacklisted = false;
+        foreach ($blacklist as $pattern => $rules) {
             if ($hostmask->matches($pattern)) {
-                return $matches;
+                $this->applyRules($iterator, $rules);
+                break;
             }
         }
+    }
 
-        // Allow event processing if appropriate 
-        return !$matches;
+    /**
+     * Clears filters on the plugin handler iterator.
+     *
+     * @return void
+     */
+    public function postDispatch()
+    {
+        $this->plugins->getIterator()->clearFilters();
     }
 }