]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - plugins/DomainWhitelist/DomainWhitelistPlugin.php
Merge remote-tracking branch 'upstream/master' into social-master
[quix0rs-gnu-social.git] / plugins / DomainWhitelist / DomainWhitelistPlugin.php
index 3add6fad9501f07fbec615a718f456440909d5ca..76486f65b041f735a0fad43efcb19c97160b6294 100644 (file)
@@ -23,6 +23,7 @@
  * @category  Cache
  * @package   StatusNet
  * @author    Evan Prodromou <evan@status.net>
+ * @author    Zach Copley <zach@status.net>
  * @copyright 2011 StatusNet, Inc.
  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
  * @link      http://status.net/
@@ -40,23 +41,73 @@ if (!defined('STATUSNET')) {
  * @category  General
  * @package   StatusNet
  * @author    Evan Prodromou <evan@status.net>
+ * @author    Zach Copley <zach@status.net>
  * @copyright 2011 StatusNet, Inc.
  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
  * @link      http://status.net/
  */
 class DomainWhitelistPlugin extends Plugin
 {
-    function onRequireValidatedEmailPlugin_Override($user, &$knownGood)
+    /**
+     * Get the path to the plugin's installation directory. Used
+     * to link in js files and whatnot.
+     *
+     * @return String the absolute path
+     */
+    protected function getPath() {
+        return preg_replace('/^' . preg_quote(INSTALLDIR, '/') . '\//', '', dirname(__FILE__));
+    }
+
+    /**
+     * Link in a JavaScript script for the whitelist invite form
+     *
+     * @param Action $action Action being shown
+     *
+     * @return boolean hook flag
+     */
+    public function onEndShowStatusNetScripts(Action $action) {
+        $name = $action->arg('action');
+        if ($name == 'invite') {
+            $action->script($this->getPath() . '/js/whitelistinvite.js');
+        }
+        return true;
+    }
+
+    public function onRequireValidatedEmailPlugin_Override(User $user, &$knownGood)
     {
         $knownGood = (!empty($user->email) && $this->matchesWhitelist($user->email));
         return true;
     }
 
-    function onStartAddEmailAddress($user, $email)
+    // @TODO Most callers are given NULL as first argument
+    public function onEndValidateUserEmail($user, $email, &$valid)
+    {
+        if ($valid) { // it's otherwise valid
+            if (!$this->matchesWhitelist($email)) {
+                $whitelist = $this->getWhitelist();
+                if (count($whitelist) == 1) {
+                    // TRANS: Client exception thrown when a given e-mailaddress is not in the domain whitelist.
+                    // TRANS: %s is a whitelisted e-mail domain.
+                    $message = sprintf(_m('Email address must be in this domain: %s.'),
+                                       $whitelist[0]);
+                } else {
+                    // TRANS: Client exception thrown when a given e-mailaddress is not in the domain whitelist.
+                    // TRANS: %s are whitelisted e-mail domains separated by comma's (localisable).
+                    $message = sprintf(_m('Email address must be in one of these domains: %s.'),
+                                       // TRANS: Separator for whitelisted domains.
+                                       implode(_m('SEPARATOR',', '), $whitelist));
+                }
+                throw new ClientException($message);
+            }
+        }
+        return true;
+    }
+
+    public function onStartAddEmailAddress(User $user, $email)
     {
         if (!$this->matchesWhitelist($email)) {
             // TRANS: Exception thrown when an e-mail address does not match the site's domain whitelist.
-            throw new Exception(_('That email address is not allowed on this site.'));
+            throw new Exception(_m('That email address is not allowed on this site.'));
         }
 
         return true;
@@ -75,33 +126,153 @@ class DomainWhitelistPlugin extends Plugin
     {
         $whitelist = $this->getWhitelist();
 
-        if (empty($whitelist)) {
+        if (empty($whitelist) || empty($whitelist[0])) {
             return true;
         }
 
-        $parts = explode('@', $email);
-
-        $userDomain = strtolower($parts[1]);
+        $userDomain = $this->domainFromEmail($email);
 
         return in_array($userDomain, $whitelist);
     }
 
+    /**
+     * Helper function to pull out a domain from
+     * an email address
+     *
+     * @param string $email and email address
+     * @return string the domain
+     */
+    function domainFromEmail($email)
+    {
+        $parts = explode('@', $email);
+        return strtolower(trim($parts[1]));
+    }
+
     function getWhitelist()
     {
         $whitelist = common_config('email', 'whitelist');
 
         if (is_array($whitelist)) {
-            return $whitelist;
+            return $this->sortWhiteList($whitelist);
         } else {
             return explode('|', $whitelist);
         }
     }
 
-    function onPluginVersion(&$versions)
+    /**
+     * This is a filter function passed in to array_filter()
+     * in order to strip out the user's domain, which will
+     * be re-inserted as the first element (see sortWhitelist()
+     * below).
+     *
+     * @param string $domain domain to check
+     * @return boolean whether to include the domain
+     */
+    function userDomainFilter($domain)
+    {
+        $user       = common_current_user();
+        $userDomain = $this->domainFromEmail($user->email);
+        if ($userDomain == $domain) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * This function sorts the whitelist alphabetically, and sets the
+     * current user's domain as the first element in the array of
+     * allowed domains. Mostly, this is for the JavaScript on the invite
+     * page--in the case of multiple allowed domains, it's nicer if the
+     * user's own domain is the first option, and this seemed like a good
+     * way to do it.
+     *
+     * @param array $whitelist whitelist of allowed email domains
+     * @return array an ordered or sorted version of the whitelist
+     */
+    function sortWhitelist($whitelist)
+    {
+        $whitelist = array_unique($whitelist);
+        natcasesort($whitelist);
+
+        $user = common_current_user();
+
+        if (!empty($user) && !empty($user->email)) {
+            $userDomain = $this->domainFromEmail($user->email);
+
+            $orderedWhitelist = array_values(
+                array_filter(
+                    $whitelist,
+                    array($this, "userDomainFilter")
+                )
+            );
+
+            if (in_array($userDomain, $whitelist)) {
+                array_unshift($orderedWhitelist, $userDomain);
+            }
+            return $orderedWhitelist;
+        }
+
+        return $whitelist;
+    }
+
+    /**
+     * Show a fancier invite form when domains are restricted to the
+     * whitelist.
+     *
+     * @param action $action the invite action
+     * @return boolean hook value
+     */
+    function onStartShowInviteForm($action)
+    {
+        $this->showConfirmDialog($action);
+        $form = new WhitelistInviteForm($action, $this->getWhitelist());
+        $form->show();
+        return false;
+    }
+
+    function showConfirmDialog($action)
+    {
+        // For JQuery UI modal dialog
+        $action->elementStart(
+            'div',
+            // TRANS: Title for invitiation deletion dialog.
+            array('id' => 'confirm-dialog', 'title' => _m('Confirmation Required'))
+        );
+        // TRANS: Confirmation text for invitation deletion dialog.
+        $action->text(_m('Really delete this invitation?'));
+        $action->elementEnd('div');
+    }
+
+    /**
+     * This is a bit of a hack. We take the values from the custom
+     * whitelist invite form and reformat them so they look like
+     * their coming from the the normal invite form.
+     *
+     * @param action &$action the invite action
+     * @return boolean hook value
+     */
+    function onStartSendInvitations(&$action)
+    {
+       $emails    = array();
+       $usernames = $action->arg('username');
+       $domains   = $action->arg('domain');
+
+       for($i = 0; $i < count($usernames); $i++) {
+           if (!empty($usernames[$i])) {
+               $emails[] = $usernames[$i] . '@' . $domains[$i] . "\n";
+           }
+       }
+
+       $action->args['addresses'] = implode($emails);
+
+       return true;
+    }
+
+    function onPluginVersion(array &$versions)
     {
         $versions[] = array('name' => 'DomainWhitelist',
-                            'version' => STATUSNET_VERSION,
-                            'author' => 'Evan Prodromou',
+                            'version' => GNUSOCIAL_VERSION,
+                            'author' => 'Evan Prodromou, Zach Copley',
                             'homepage' => 'http://status.net/wiki/Plugin:DomainWhitelist',
                             'rawdescription' =>
                             // TRANS: Plugin description.