]> git.mjollnir.org Git - s9y.git/commitdiff
backport akismet support
authorgarvinhicking <garvinhicking>
Tue, 18 Apr 2006 10:06:57 +0000 (10:06 +0000)
committergarvinhicking <garvinhicking>
Tue, 18 Apr 2006 10:06:57 +0000 (10:06 +0000)
docs/NEWS
plugins/serendipity_event_spamblock/lang_en.inc.php
plugins/serendipity_event_spamblock/serendipity_event_spamblock.php

index 58d486cac5cbb3adadf255b5d51651927e395f2a..beb22c322930d8bbd53958fa87f1532ef4fa6bb8 100644 (file)
--- a/docs/NEWS
+++ b/docs/NEWS
@@ -3,6 +3,8 @@
 Version 1.0 ()
 ------------------------------------------------------------------------
 
+   * Add Akismet antispam support (garvinhicking)
+
    * Saving special crafterd configuration data as Admin superuser 
      could lead to arbitrary PHP code inclusion from 
      serendipity_config_local.inc.php. Since admins usually already have
index bc98a2d93752567873876896a88c909e1c5b5846..3a3fce8402bf286b39c0cebce97b72b21dd63ae5 100644 (file)
 
 @define('PLUGIN_EVENT_SPAMBLOCK_HIDE', 'Disable spamblock for Authors');
 @define('PLUGIN_EVENT_SPAMBLOCK_HIDE_DESC', 'You can allow authors in the following usergroups to post comments without them being checked by the spamblock plugin.');
+
+@define('PLUGIN_EVENT_SPAMBLOCK_AKISMET', 'Akismet API Key');
+@define('PLUGIN_EVENT_SPAMBLOCK_AKISMET_DESC', 'Akismet.com is a central anti-spam and blacklisting server. It can analyze your incoming comments and check if that comment has been listed as Spam. Akismet was developed for WordPress specifically, but can be used by other systems. You just need an API Key from http://www.akismet.com by registering an account at http://www.wordpress.com/. If you leave this API key empty, Akismet will not be used.');
+@define('PLUGIN_EVENT_SPAMBLOCK_AKISMET_FILTER', 'How to treat Akismet-reported spam');
+@define('PLUGIN_EVENT_SPAMBLOCK_REASON_AKISMET_SPAMLIST', 'Filtered by Akismet.com Blacklist');
+
index 5c78d8e3489c0a52fc4857eb1e96bf02b1c90075..c7f3ec971d68de02b9a2944a7f818d0e2720391e 100644 (file)
@@ -34,7 +34,7 @@ var $filter_defaults;
             'smarty'      => '2.6.7',
             'php'         => '4.1.0'
         ));
-        $propbag->add('version',       '1.40');
+        $propbag->add('version',       '1.50');
         $propbag->add('event_hooks',    array(
             'frontend_saveComment' => true,
             'external_plugin'      => true,
@@ -43,7 +43,31 @@ var $filter_defaults;
             'backend_comments_top' => true,
             'backend_view_comment' => true
         ));
-        $propbag->add('configuration', array('killswitch', 'hide_for_authors', 'bodyclone', 'entrytitle', 'ipflood', 'captchas', 'captchas_ttl', 'captcha_color', 'forcemoderation', 'disable_api_comments', 'trackback_check_url', 'links_moderate', 'links_reject', 'contentfilter_activate', 'contentfilter_urls', 'bloggdeblacklist', 'contentfilter_authors', 'hide_email', 'checkmail', 'required_fields', 'logtype', 'logfile'));
+        $propbag->add('configuration', array(
+            'killswitch',
+            'hide_for_authors',
+            'bodyclone',
+            'entrytitle',
+            'ipflood',
+            'captchas',
+            'captchas_ttl',
+            'captcha_color',
+            'forcemoderation',
+            'disable_api_comments',
+            'trackback_check_url',
+            'links_moderate',
+            'links_reject',
+            'contentfilter_activate',
+            'contentfilter_urls',
+            'contentfilter_authors',
+            'bloggdeblacklist',
+            'akismet',
+            'akismet_filter',
+            'hide_email',
+            'checkmail',
+            'required_fields',
+            'logtype',
+            'logfile'));
         $propbag->add('groups', array('ANTISPAM'));
 
         $this->filter_defaults = array(
@@ -176,6 +200,32 @@ var $filter_defaults;
 
                 break;
 
+            case 'akismet':
+                $propbag->add('type', 'string');
+                $propbag->add('name', PLUGIN_EVENT_SPAMBLOCK_AKISMET);
+                $propbag->add('description', PLUGIN_EVENT_SPAMBLOCK_AKISMET_DESC);
+                $propbag->add('default', '');
+                $propbag->add('radio', array(
+                    'value' => array('moderate', 'reject', 'none'),
+                    'desc'  => array(PLUGIN_EVENT_SPAMBLOCK_API_MODERATE, PLUGIN_EVENT_SPAMBLOCK_API_REJECT, NONE)
+                ));
+                $propbag->add('radio_per_row', '1');
+
+                break;
+
+            case 'akismet_filter':
+                $propbag->add('type', 'radio');
+                $propbag->add('name', PLUGIN_EVENT_SPAMBLOCK_AKISMET_FILTER);
+                $propbag->add('description', '');
+                $propbag->add('default', 'reject');
+                $propbag->add('radio', array(
+                    'value' => array('moderate', 'reject', 'none'),
+                    'desc'  => array(PLUGIN_EVENT_SPAMBLOCK_API_MODERATE, PLUGIN_EVENT_SPAMBLOCK_API_REJECT, NONE)
+                ));
+                $propbag->add('radio_per_row', '1');
+
+                break;
+
             case 'contentfilter_urls':
                 $propbag->add('type', 'text');
                 $propbag->add('name', PLUGIN_EVENT_SPAMBLOCK_FILTER_URLS);
@@ -267,10 +317,95 @@ var $filter_defaults;
         return true;
     }
 
-    function getBlacklist($where) {
+    function &getBlacklist($where, $api_key = '', &$eventData, &$addData) {
         global $serendipity;
 
+        $ret = false;
+        if (function_exists('serendipity_request_start')) serendipity_request_start();
         switch($where) {
+            case 'akismet.com':
+                $ret  = array();
+                       $data = array(
+                         'blog'                    => $serendipity['baseURL'],
+                         'user_agent'              => $_SERVER['HTTP_USER_AGENT'],
+                         'referrer'                => $_SERVER['HTTP_REFERER'],
+                         'user_ip'                 => $_SERVER['REMOTE_ADDR'] != getenv('SERVER_ADDR') ? $_SERVER['REMOTE_ADDR'] : getenv('HTTP_X_FORWARDED_FOR'),
+                         'permalink'               => serendipity_archiveURL($eventData['id'], $eventData['title'], 'serendipityHTTPPath', true, array('timestamp' => $eventData['timestamp'])),
+                         'comment_type'            => ($addData['type'] == 'NORMAL' ? 'comment' : 'trackback'),
+                         'comment_author'          => $addData['name'],
+                         'comment_author_email'    => $addData['email'],
+                         'comment_author_url'      => $addData['url'],
+                         'comment_content'         => $addData['comment']
+                );
+                $opt = array(
+                    'method'            => 'POST',
+                    'http'              => '1.1',
+                    'timeout'           => 20,
+                    'allowRedirects'    => true,
+                    'maxRedirects'      => 3
+                );
+
+                require_once S9Y_PEAR_PATH . 'HTTP/Request.php';
+
+                $req    = &new HTTP_Request(
+                    'http://rest.akismet.com/1.1/verify-key',
+                     $opt
+                );
+
+                $req->addPostData('key',  $api_key);
+                $req->addPostData('blog', $serendipity['baseURL']);
+
+                if (PEAR::isError($req->sendRequest()) || $req->getResponseCode() != '200') {
+                    $ret['is_spam'] = false;
+                    $ret['message'] = 'API Verification Request failed';
+                    $this->log($this->logfile, $eventData['id'], 'API_ERROR', 'Akismet HTTP verification request failed.', $addData);
+                    break;
+                } else {
+                    // Fetch response
+                    $reqdata = $req->getResponseBody();
+                }
+
+                if (!preg_match('@valid@i', $reqdata)) {
+                    $ret['is_spam'] = false;
+                    $ret['message'] = 'API Verification failed';
+                    $this->log($this->logfile, $eventData['id'], 'API_ERROR', 'Akismet API verification failed: ' . $reqdata, $addData);
+                    break;
+                }
+
+                $req    = &new HTTP_Request(
+                    'http://' . $api_key . '.rest.akismet.com/1.1/comment-check',
+                    $opt
+                );
+
+                foreach($data AS $key => $value) {
+                    $req->addPostData($key, $value);
+                }
+
+                if (PEAR::isError($req->sendRequest()) || $req->getResponseCode() != '200') {
+                    $ret['is_spam'] = false;
+                    $ret['message'] = 'Akismet Request failed';
+                    $this->log($this->logfile, $eventData['id'], 'API_ERROR', 'Akismet HTTP request failed.', $addData);
+                    break;
+                } else {
+                    // Fetch response
+                    $reqdata = $req->getResponseBody();
+                }
+
+                if (preg_match('@true@i', $reqdata)) {
+                    $ret['is_spam'] = true;
+                    $ret['message'] = $reqdata;
+                } elseif (preg_match('@false@i', $reqdata)) {
+                    $ret['is_spam'] = false;
+                    $ret['message'] = $reqdata;
+                    $this->log($this->logfile, $eventData['id'], 'API_ERROR', 'Akismet API verification failed: ' . $reqdata, $addData);
+                } else {
+                    $ret['is_spam'] = false;
+                    $ret['message'] = 'Akismet API failure';
+                    $this->log($this->logfile, $eventData['id'], 'API_ERROR', 'Akismet API failure: ' . $reqdata, $addData);
+                }
+
+                break;
+
             case 'blogg.de':
                 $target  = $serendipity['serendipityPath'] . PATH_SMARTY_COMPILE . '/blogg.de.blacklist.txt';
                 $timeout = 3600; // One hour
@@ -279,7 +414,7 @@ var $filter_defaults;
                     $data = file_get_contents($target);
                 } else {
                     $data = '';
-                    require_once S9Y_PEAR_PATH . 'HTTP/Request.php';
+
                     $req    = &new HTTP_Request('http://spam.blogg.de/blacklist.txt');
 
                     if (PEAR::isError($req->sendRequest()) || $req->getResponseCode() != '200') {
@@ -299,11 +434,14 @@ var $filter_defaults;
                 }
 
                 $blacklist = explode("\n", $data);
-                return $blacklist;
+                $ret =& $blacklist;
 
             default:
-                return false;
+                break;
         }
+
+        if (function_exists('serendipity_request_end')) serendipity_request_end();
+        return $ret;
     }
 
     function checkScheme($maxVersion) {
@@ -416,7 +554,7 @@ var $filter_defaults;
                         }
 
                         $serendipity['csuccess'] = 'true';
-                        $logfile = $this->get_config('logfile', $serendipity['serendipityPath'] . 'spamblock.log');
+                        $logfile = $this->logfile = $this->get_config('logfile', $serendipity['serendipityPath'] . 'spamblock.log');
                         $required_fields = $this->get_config('required_fields', '');
 
                         // Check required fields
@@ -470,10 +608,31 @@ var $filter_defaults;
                             }
                         }
 
+                        // Filter Akismet Blacklist?
+                        $akismet_apikey = $this->get_config('akismet');
+                        $akismet        = $this->get_config('akismet_filter');
+                        if (!empty($akismet_apikey) && ($akismet == 'moderate' || $akismet == 'reject')) {
+                            $spam = $this->getBlacklist('akismet.com', $akismet_apikey, $eventData, $addData);
+                            if ($spam['is_spam'] !== false) {
+                                if ($akismet == 'moderate') {
+                                    $this->log($logfile, $eventData['id'], 'MODERATE', PLUGIN_EVENT_SPAMBLOCK_REASON_AKISMET_SPAMLIST . ': ' . $spam['message'], $addData);
+                                    $eventData['moderate_comments'] = true;
+                                    $serendipity['csuccess']        = 'moderate';
+                                    $serendipity['moderate_reason'] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
+                                } else {
+                                    $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_AKISMET_SPAMLIST . ': ' . $spam['message'], $addData);
+                                    $eventData = array('allow_comments' => false);
+                                    $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
+                                    return false;
+                                }
+                            }
+                        }
+
                         // Check Trackback URLs?
                         if ($addData['type'] == 'TRACKBACK' && serendipity_db_bool($this->get_config('trackback_check_url'))) {
                             require_once S9Y_PEAR_PATH . 'HTTP/Request.php';
 
+                            if (function_exists('serendipity_request_start')) serendipity_request_start();
                             $req     = &new HTTP_Request($addData['url'], array('allowRedirects' => true, 'maxRedirects' => 5));
                             $is_valid = false;
                             if (PEAR::isError($req->sendRequest()) || $req->getResponseCode() != '200') {
@@ -488,6 +647,7 @@ var $filter_defaults;
                                     $is_valid = false;
                                 }
                             }
+                            if (function_exists('serendipity_request_end')) serendipity_request_end();
 
                             if ($is_valid === false) {
                                 $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_TRACKBACKURL, $addData);
@@ -544,54 +704,54 @@ var $filter_defaults;
                                         }
                                     }
                                 }
+                            }
 
-                                // Filter Content
-                                $filter_bodys = explode(';', $this->get_config('contentfilter_words', $this->filter_defaults['words']));
-                                if (is_array($filter_bodys)) {
-                                    foreach($filter_bodys AS $filter_body) {
-                                        if (empty($filter_body)) {
-                                            continue;
-                                        }
-                                        if (preg_match('@' . $filter_body . '@', $addData['comment'])) {
-                                            if ($filter_type == 'moderate') {
-                                                $this->log($logfile, $eventData['id'], 'MODERATE', PLUGIN_EVENT_SPAMBLOCK_FILTER_WORDS, $addData);
-                                                $eventData['moderate_comments'] = true;
-                                                $serendipity['csuccess']        = 'moderate';
-                                                $serendipity['moderate_reason'] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
-                                            } else {
-                                                $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_FILTER_WORDS, $addData);
-                                                $eventData = array('allow_comments' => false);
-                                                $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
-                                                return false;
-                                            }
+                            // Filter Content
+                            $filter_bodys = explode(';', $this->get_config('contentfilter_words', $this->filter_defaults['words']));
+                            if (is_array($filter_bodys)) {
+                                foreach($filter_bodys AS $filter_body) {
+                                    if (empty($filter_body)) {
+                                        continue;
+                                    }
+                                    if (preg_match('@' . $filter_body . '@', $addData['comment'])) {
+                                        if ($filter_type == 'moderate') {
+                                            $this->log($logfile, $eventData['id'], 'MODERATE', PLUGIN_EVENT_SPAMBLOCK_FILTER_WORDS, $addData);
+                                            $eventData['moderate_comments'] = true;
+                                            $serendipity['csuccess']        = 'moderate';
+                                            $serendipity['moderate_reason'] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
+                                        } else {
+                                            $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_FILTER_WORDS, $addData);
+                                            $eventData = array('allow_comments' => false);
+                                            $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
+                                            return false;
                                         }
                                     }
                                 }
                             }
+                        } // Content filtering end
+
+                        // Filter Blogg.de Blacklist?
+                        $bloggdeblacklist = $this->get_config('bloggdeblacklist');
+                        if ($bloggdeblacklist == 'moderate' || $bloggdeblacklist == 'reject') {
+                            $domains = $this->getBlacklist('blogg.de', '', $eventData, $addData);
+                            if (is_array($domains)) {
+                                foreach($domains AS $domain) {
+                                    $domain = trim($domain);
+                                    if (empty($domain)) {
+                                        continue;
+                                    }
 
-                            // Filter Blogg.de Blacklist?
-                            $bloggdeblacklist = $this->get_config('bloggdeblacklist');
-                            if ($bloggdeblacklist == 'moderate' || $bloggdeblacklist == 'reject') {
-                                $domains = $this->getBlacklist('blogg.de');
-                                if (is_array($domains)) {
-                                    foreach($domains AS $domain) {
-                                        $domain = trim($domain);
-                                        if (empty($domain)) {
-                                            continue;
-                                        }
-
-                                        if (preg_match('@' . preg_quote($domain) . '@i', $addData['url'])) {
-                                            if ($bloggdeblacklist == 'moderate') {
-                                                $this->log($logfile, $eventData['id'], 'MODERATE', PLUGIN_EVENT_SPAMBLOCK_REASON_BLOGG_SPAMLIST . ': ' . $domain, $addData);
-                                                $eventData['moderate_comments'] = true;
-                                                $serendipity['csuccess']        = 'moderate';
-                                                $serendipity['moderate_reason'] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
-                                            } else {
-                                                $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_BLOGG_SPAMLIST . ': ' . $domain, $addData);
-                                                $eventData = array('allow_comments' => false);
-                                                $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
-                                                return false;
-                                            }
+                                    if (preg_match('@' . preg_quote($domain) . '@i', $addData['url'])) {
+                                        if ($bloggdeblacklist == 'moderate') {
+                                            $this->log($logfile, $eventData['id'], 'MODERATE', PLUGIN_EVENT_SPAMBLOCK_REASON_BLOGG_SPAMLIST . ': ' . $domain, $addData);
+                                            $eventData['moderate_comments'] = true;
+                                            $serendipity['csuccess']        = 'moderate';
+                                            $serendipity['moderate_reason'] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
+                                        } else {
+                                            $this->log($logfile, $eventData['id'], 'REJECTED', PLUGIN_EVENT_SPAMBLOCK_REASON_BLOGG_SPAMLIST . ': ' . $domain, $addData);
+                                            $eventData = array('allow_comments' => false);
+                                            $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_SPAMBLOCK_ERROR_BODY;
+                                            return false;
                                         }
                                     }
                                 }