diff options
author | Luke Fitzgerald <lw.fitzgerald@googlemail.com> | 2010-07-23 13:33:41 -0700 |
---|---|---|
committer | Luke Fitzgerald <lw.fitzgerald@googlemail.com> | 2010-07-23 13:33:41 -0700 |
commit | c4640c50d38c6f05cd6c076a5cb17656fb72240e (patch) | |
tree | f951cf5b3d14afdb3bc4d73f15ee4c66e0de746e | |
parent | f818182a373f10abac49cb476a0f16dbaf051965 (diff) |
Lots more work - Implemented nickname checking
-rw-r--r-- | plugins/Irc/Fake_Irc.php | 2 | ||||
-rw-r--r-- | plugins/Irc/IrcPlugin.php | 78 | ||||
-rw-r--r-- | plugins/Irc/README | 5 | ||||
-rw-r--r-- | plugins/Irc/extlib/phergie/Phergie/Driver/Statusnet.php | 13 | ||||
-rw-r--r-- | plugins/Irc/extlib/phergie/Phergie/Plugin/NickServ.php | 4 | ||||
-rw-r--r-- | plugins/Irc/extlib/phergie/Phergie/Plugin/Statusnet.php | 98 | ||||
-rw-r--r-- | plugins/Irc/extlib/phergie/Phergie/Plugin/StatusnetCallback.php | 63 | ||||
-rw-r--r-- | plugins/Irc/extlib/phergie/Phergie/Plugin/patch.diff | 22 | ||||
-rw-r--r-- | plugins/Irc/extlib/phergie/Phergie/StatusnetBot.php | 21 | ||||
-rw-r--r-- | plugins/Irc/ircmanager.php | 82 |
10 files changed, 306 insertions, 82 deletions
diff --git a/plugins/Irc/Fake_Irc.php b/plugins/Irc/Fake_Irc.php index a1e296e8b..71892abf6 100644 --- a/plugins/Irc/Fake_Irc.php +++ b/plugins/Irc/Fake_Irc.php @@ -35,6 +35,6 @@ class Fake_Irc extends Phergie_Driver_Streams { public $would_be_sent = null; protected function send($command, $args = '') { - $this->would_be_sent = array($command, $args); + $this->would_be_sent = array('command' => $command, 'args' => $args); } } diff --git a/plugins/Irc/IrcPlugin.php b/plugins/Irc/IrcPlugin.php index a9044df8d..ce8f31784 100644 --- a/plugins/Irc/IrcPlugin.php +++ b/plugins/Irc/IrcPlugin.php @@ -60,7 +60,10 @@ class IrcPlugin extends ImPlugin { public $transporttype = null; public $encoding = null; + public $regcheck = null; + public $transport = 'irc'; + public $fake_irc; /** * Get the internationalized/translated display name of this IM service @@ -160,7 +163,33 @@ class IrcPlugin extends ImPlugin { */ public function send_message($screenname, $body) { $this->fake_irc->doPrivmsg($screenname, $body); - $this->enqueue_outgoing_raw($this->fake_irc->would_be_sent); + $this->enqueue_outgoing_raw(array('type' => 'message', 'data' => $this->fake_irc->would_be_sent)); + return true; + } + + /** + * Only sends the confirmation message if the nick is + * registered + * + * @param string $screenname screenname sending to + * @param string $code the confirmation code + * @param User $user user sending to + * @return boolean success value + */ + public function checked_send_confirmation_code($screenname, $code, $user) { + $this->fake_irc->doPrivmsg('NickServ', 'INFO '.$screenname); + $this->enqueue_outgoing_raw( + array( + 'type' => 'nickcheck', + 'data' => $this->fake_irc->would_be_sent, + 'nickdata' => + array( + 'screenname' => $screenname, + 'code' => $code, + 'user' => $user + ) + ) + ); return true; } @@ -175,6 +204,30 @@ class IrcPlugin extends ImPlugin { } /** + * Send a confirmation code to a user + * + * @param string $screenname screenname sending to + * @param string $code the confirmation code + * @param User $user user sending to + * @return boolean success value + */ + public function send_confirmation_code($screenname, $code, $user, $checked = false) { + $body = sprintf(_('User "%s" on %s has said that your %s screenname belongs to them. ' . + 'If that\'s true, you can confirm by clicking on this URL: ' . + '%s' . + ' . (If you cannot click it, copy-and-paste it into the ' . + 'address bar of your browser). If that user isn\'t you, ' . + 'or if you didn\'t request this confirmation, just ignore this message.'), + $user->nickname, common_config('site', 'name'), $this->getDisplayName(), common_local_url('confirmaddress', array('code' => $code))); + + if ($this->regcheck && !$checked) { + return $this->checked_send_confirmation_code($screenname, $code, $user); + } else { + return $this->send_message($screenname, $body); + } + } + + /** * Initialize plugin * * @return boolean @@ -193,6 +246,29 @@ class IrcPlugin extends ImPlugin { throw new Exception('must specify a nickname'); } + if (!isset($this->port)) { + $this->port = 6667; + } + if (!isset($this->password)) { + $this->password = ''; + } + if (!isset($this->transporttype)) { + $this->transporttype = 'tcp'; + } + if (!isset($this->encoding)) { + $this->encoding = 'UTF-8'; + } + if (!isset($this->nickservpassword)) { + $this->nickservpassword = ''; + } + if (!isset($this->channels)) { + $this->channels = array(); + } + + if (!isset($this->regcheck)) { + $this->regcheck = true; + } + $this->fake_irc = new Fake_Irc; return true; } diff --git a/plugins/Irc/README b/plugins/Irc/README index 2429a5b81..79ce8ff56 100644 --- a/plugins/Irc/README +++ b/plugins/Irc/README @@ -22,6 +22,11 @@ nickservpassword: NickServ password for identification channels: Channels for bot to idle in transporttype: Set to 'ssl' to enable SSL encoding: Set to change encoding +regcheck: Check user's nicknames are registered, enabled by default, set to false to disable +regregexp: Override existing regexp matching response from NickServ if nick checked is registered. + Must contain a capturing group catching the nick +unregregexp: Override existing regexp matching response from NickServ if nick checked is unregistered + Must contain a capturing group catching the nick * required diff --git a/plugins/Irc/extlib/phergie/Phergie/Driver/Statusnet.php b/plugins/Irc/extlib/phergie/Phergie/Driver/Statusnet.php index 48540069c..6a0cbb8d1 100644 --- a/plugins/Irc/extlib/phergie/Phergie/Driver/Statusnet.php +++ b/plugins/Irc/extlib/phergie/Phergie/Driver/Statusnet.php @@ -42,6 +42,19 @@ class Phergie_Driver_Statusnet extends Phergie_Driver_Streams { return parent::send($command, $args);
}
+ public function forceQuit() {
+ try {
+ // Send a QUIT command to the server
+ $this->send('QUIT', 'Reconnecting');
+ } catch (Phergie_Driver_Exception $e){}
+
+ // Terminate the socket connection
+ fclose($this->socket);
+
+ // Remove the socket from the internal socket list
+ unset($this->sockets[(string) $this->getConnection()->getHostmask()]);
+ }
+
/**
* Returns the array of sockets
*
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/NickServ.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/NickServ.php index ff181d94e..f873c753b 100644 --- a/plugins/Irc/extlib/phergie/Phergie/Plugin/NickServ.php +++ b/plugins/Irc/extlib/phergie/Phergie/Plugin/NickServ.php @@ -65,7 +65,7 @@ class Phergie_Plugin_NickServ extends Phergie_Plugin_Abstract // Get the identify message
$this->identifyMessage = $this->config['nickserv.identify_message'];
if (!$this->identifyMessage) {
- $this->identifyMessage = 'This nickname is registered.';
+ $this->identifyMessage = '/This nickname is registered./';
}
}
@@ -82,7 +82,7 @@ class Phergie_Plugin_NickServ extends Phergie_Plugin_Abstract if (strtolower($event->getNick()) == strtolower($this->botNick)) {
$message = $event->getArgument(1);
$nick = $this->connection->getNick();
- if (strpos($message, $this->identifyMessage) !== false) {
+ if (preg_match($this->identifyMessage, $message)) {
$password = $this->config['nickserv.password'];
if (!empty($password)) {
$this->doPrivmsg($this->botNick, 'IDENTIFY ' . $password);
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/Statusnet.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/Statusnet.php new file mode 100644 index 000000000..71b7b06bc --- /dev/null +++ b/plugins/Irc/extlib/phergie/Phergie/Plugin/Statusnet.php @@ -0,0 +1,98 @@ +<?php
+/**
+ * StatusNet - the distributed open-source microblogging tool
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Calls the given Statusnet IM architecture enqueuing method to enqueue
+ * a new incoming message
+ *
+ * @category Phergie
+ * @package Phergie_Plugin_Statusnet
+ * @author Luke Fitzgerald <lw.fitzgerald@googlemail.com>
+ * @copyright 2010 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
+ * @link http://status.net/
+ */
+
+class Phergie_Plugin_Statusnet extends Phergie_Plugin_Abstract {
+ /**
+ * Message callback details
+ *
+ * @var array
+ */
+ protected $messageCallback;
+
+ protected $regCallback;
+
+ protected $tocheck = array();
+
+ /**
+ * Load callback from config
+ */
+ public function onLoad() {
+ $messageCallback = $this->config['statusnet.messagecallback'];
+ if (is_callable($messageCallback)) {
+ $this->messageCallback = $messageCallback;
+ } else {
+ $this->messageCallback = NULL;
+ }
+
+ $regCallback = $this->config['statusnet.regcallback'];
+ if (is_callable($regCallback)) {
+ $this->regCallback = $regCallback;
+ } else {
+ $this->regCallback = NULL;
+ }
+
+ $this->unregRegexp = $this->config['statusnet.unregregexp'];
+ if (!$this->unregRegexp) {
+ $this->unregRegexp = '/\x02(.*?)\x02 (?:isn\'t|is not) registered/i';
+ }
+
+ $this->regRegexp = $this->config['statusnet.regregexp'];
+ if (!$this->regRegexp) {
+ $this->regRegexp = '/(?:\A|\x02)(\w+?)\x02? (?:\(account|is \w+?\z)/i';
+ }
+ }
+
+ /**
+ * Passes incoming messages to StatusNet
+ *
+ * @return void
+ */
+ public function onPrivmsg() {
+ if ($this->messageCallback !== NULL) {
+ $event = $this->getEvent();
+ $source = $event->getSource();
+ $message = trim($event->getText());
+
+ call_user_func($this->messageCallback, array('sender' => $source, 'message' => $message));
+ }
+ }
+
+ public function onNotice() {
+ $event = $this->getEvent();
+ if ($event->getNick() == 'NickServ') {
+ $message = $event->getArgument(1);
+ if (preg_match($this->unregRegexp, $message, $groups)) {
+ $nick = $groups[1];
+ call_user_func($this->regCallback, array('nick' => $nick, 'registered' => false));
+ } elseif (preg_match($this->regRegexp, $message, $groups)) {
+ $nick = $groups[1];
+ call_user_func($this->regCallback, array('nick' => $nick, 'registered' => true));
+ }
+ }
+ }
+}
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/StatusnetCallback.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/StatusnetCallback.php deleted file mode 100644 index 545ee343b..000000000 --- a/plugins/Irc/extlib/phergie/Phergie/Plugin/StatusnetCallback.php +++ /dev/null @@ -1,63 +0,0 @@ -<?php
-/**
- * StatusNet - the distributed open-source microblogging tool
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * Calls the given Statusnet IM architecture enqueuing method to enqueue
- * a new incoming message
- *
- * @category Phergie
- * @package Phergie_Plugin_StatusnetCallback
- * @author Luke Fitzgerald <lw.fitzgerald@googlemail.com>
- * @copyright 2010 StatusNet, Inc.
- * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
- * @link http://status.net/
- */
-
-class Phergie_Plugin_StatusnetCallback extends Phergie_Plugin_Abstract {
- /**
- * Callback details
- *
- * @var array
- */
- protected $callback;
-
- /**
- * Load callback from config
- */
- public function onLoad() {
- $callback = $this->config['statusnetcallback.callback'];
- if (is_callable($callback)) {
- $this->callback = $callback;
- } else {
- $this->callback = NULL;
- }
- }
-
- /**
- * Passes incoming messages to StatusNet
- *
- * @return void
- */
- public function onPrivmsg() {
- if ($this->callback !== NULL) {
- $event = $this->getEvent();
- $source = $event->getSource();
- $message = trim($event->getText());
-
- call_user_func($this->callback, array('sender' => $source, 'message' => $message));
- }
- }
-}
diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/patch.diff b/plugins/Irc/extlib/phergie/Phergie/Plugin/patch.diff new file mode 100644 index 000000000..9cfa3c2b8 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Phergie/Plugin/patch.diff @@ -0,0 +1,22 @@ +diff --git a/plugins/Irc/extlib/phergie/Phergie/Plugin/NickServ.php b/plugins/Irc/extlib/phergie/Phergie/Plugin/NickServ.php +index ff181d9..f873c75 100644 +--- a/plugins/Irc/extlib/phergie/Phergie/Plugin/NickServ.php ++++ b/plugins/Irc/extlib/phergie/Phergie/Plugin/NickServ.php +@@ -65,7 +65,7 @@ class Phergie_Plugin_NickServ extends Phergie_Plugin_Abstract + // Get the identify message
+ $this->identifyMessage = $this->config['nickserv.identify_message'];
+ if (!$this->identifyMessage) {
+- $this->identifyMessage = 'This nickname is registered.';
++ $this->identifyMessage = '/This nickname is registered./';
+ }
+ }
+
+@@ -82,7 +82,7 @@ class Phergie_Plugin_NickServ extends Phergie_Plugin_Abstract + if (strtolower($event->getNick()) == strtolower($this->botNick)) {
+ $message = $event->getArgument(1);
+ $nick = $this->connection->getNick();
+- if (strpos($message, $this->identifyMessage) !== false) {
++ if (preg_match($this->identifyMessage, $message)) {
+ $password = $this->config['nickserv.password'];
+ if (!empty($password)) {
+ $this->doPrivmsg($this->botNick, 'IDENTIFY ' . $password);
diff --git a/plugins/Irc/extlib/phergie/Phergie/StatusnetBot.php b/plugins/Irc/extlib/phergie/Phergie/StatusnetBot.php index ba41f26db..5fe65444b 100644 --- a/plugins/Irc/extlib/phergie/Phergie/StatusnetBot.php +++ b/plugins/Irc/extlib/phergie/Phergie/StatusnetBot.php @@ -67,6 +67,27 @@ class Phergie_StatusnetBot extends Phergie_Bot { }
/**
+ * Close the current connection and reconnect to the server
+ *
+ * @return void
+ */
+ public function reconnect() {
+ $driver = $this->getDriver();
+ $sockets = $driver->getSockets();
+
+ // Close any existing connections
+ try {
+ $driver->forceQuit();
+ } catch (Phergie_Driver_Exception $e){}
+ try {
+ $driver->doConnect();
+ } catch (Phergie_Driver_Exception $e){
+ $driver->forceQuit();
+ throw $e;
+ }
+ }
+
+ /**
* Get the sockets used by the bot
*
* @return array Array of socket resources
diff --git a/plugins/Irc/ircmanager.php b/plugins/Irc/ircmanager.php index 741b324a9..93513df86 100644 --- a/plugins/Irc/ircmanager.php +++ b/plugins/Irc/ircmanager.php @@ -32,6 +32,8 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } class IrcManager extends ImManager { public $conn = null; + public $regchecks = array(); + public $regchecksLookup = array(); /** * Initialize connection to server. @@ -83,13 +85,6 @@ class IrcManager extends ImManager { if (!$this->conn) { $this->conn = new Phergie_StatusnetBot; - $port = empty($this->plugin->port) ? 6667 : $this->plugin->port; - $password = empty($this->plugin->password) ? '' : $this->plugin->password; - $transport = empty($this->plugin->transporttype) ? 'tcp' : $this->plugin->transporttype; - $encoding = empty($this->plugin->encoding) ? 'UTF-8' : $this->plugin->encoding; - $nickservpassword = empty($this->plugin->nickservpassword) ? '' : $this->plugin->nickservpassword; - $channels = empty($this->plugin->channels) ? array() : $this->plugin->channels; - $config = new Phergie_Config; $config->readArray( array( @@ -100,9 +95,9 @@ class IrcManager extends ImManager { 'username' => $this->plugin->username, 'realname' => $this->plugin->realname, 'nick' => $this->plugin->nick, - 'password' => $password, - 'transport' => $transport, - 'encoding' => $encoding + 'password' => $this->plugin->password, + 'transport' => $this->plugin->transporttype, + 'encoding' => $this->plugin->encoding ) ), @@ -114,16 +109,17 @@ class IrcManager extends ImManager { 'Pong', 'NickServ', 'AutoJoin', - 'StatusnetCallback', + 'Statusnet', ), 'plugins.autoload' => true, 'ui.enabled' => true, - 'nickserv.password' => $nickservpassword, - 'autojoin.channels' => $channels, - 'statusnetcallback.callback' => array($this, 'handle_irc_message') + 'nickserv.password' => $this->plugin->nickservpassword, + 'autojoin.channels' => $this->plugin->channels, + 'statusnet.messagecallback' => array($this, 'handle_irc_message'), + 'statusnet.regcallback' => array($this, 'handle_reg_response') ) ); @@ -147,6 +143,47 @@ class IrcManager extends ImManager { } /** + * Called via a callback when NickServ responds to + * the bots query asking if a nick is registered + * + * @param array $data Data + * @return void + */ + public function handle_reg_response($data) { + // Retrieve data + $nickdata = $this->regchecks[$data['nick']]; + + if ($data['registered']) { + // Send message + $this->plugin->send_confirmation_code($nickdata['screenname'], $nickdata['code'], $nickdata['user'], true); + } else { + $this->plugin->send_message($nickdata['screenname'], _m('Your nickname is not registered so IRC connectivity cannot be enabled')); + + $confirm = new Confirm_address(); + + $confirm->user_id = $user->id; + $confirm->address_type = $this->plugin->transport; + + if ($confirm->find(true)) { + $result = $confirm->delete(); + + if (!$result) { + common_log_db_error($confirm, 'DELETE', __FILE__); + // TRANS: Server error thrown on database error canceling IM address confirmation. + $this->serverError(_('Couldn\'t delete confirmation.')); + return; + } + } + } + + // Unset lookup value + unset($this->regchecksLookup[$nickdata['screenname']]); + + // Unset data + unset($this->regchecks[$data['nick']]); + } + + /** * Send a message using the daemon * * @param $data Message @@ -157,7 +194,22 @@ class IrcManager extends ImManager { if (!$this->conn) { return false; } - $this->conn->send($data[0], $data[1]); + if ($data['type'] != 'message') { + // Nick checking + $screenname = $data['nickdata']['screenname']; + if (isset($this->regchecksLookup[$user->nickname])) { + + } + $this->regchecks[$screenname] = $data['nickdata']; + $this->regchecksLookup[$user->nickname] = $screenname; + } + + try { + $this->conn->send($data['data']['command'], $data['data']['args']); + } catch (Phergie_Driver_Exception $e) { + $this->conn->reconnect(); + return false; + } return true; } } |