Skip to content

Commit

Permalink
add Akismet
Browse files Browse the repository at this point in the history
  • Loading branch information
skywalker512 committed Jul 7, 2018
1 parent c1ef412 commit 9ee530a
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 0 deletions.
2 changes: 2 additions & 0 deletions addons/plugins/Akismet/README.md
@@ -0,0 +1,2 @@
# esotalk-akismet
Anti-spammer plugin for esotalk
Binary file added addons/plugins/Akismet/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file.
178 changes: 178 additions & 0 deletions addons/plugins/Akismet/plugin.php
@@ -0,0 +1,178 @@
<?php

if (!defined('IN_ESOTALK')) exit;

ET::$pluginInfo['Akismet'] = array(
'name' => 'Akismet',
'description' => '使用akismet来防止垃圾信息',
'version' => ETPlugin_Akismet::VERSION,
'author' => 'rhyzx',
'authorEmail' => 'rhyzix@gmail.com',
'authorURL' => 'https://github.com/rhyzx',
'license' => 'MIT',
'priority' => 0,
);

class ETPlugin_Akismet extends ETPlugin {
const VERSION = '0.2.0';
private $message = 'spammer detected';

public function handler_userController_initJoin($sender, $form)
{
// TODO? honeypot
// $form->addSection('akismet');
$form->addField('akismet', 'akismet', function($form)
{
// return $form->input('akismet', 'text');
},
function($form, $key, &$data) use ($sender)
{
if ( $this->isSpam($data['username'], $data['email'], '', 'registration') ) {
// TODO message and i18n
$sender->message($this->message, 'warning');
$form->error($key, $this->message);
}
});
}

public function handler_conversationController_reply($sender, $form)
{
$user = ET::$session->user;

if ( $this->userPostCountLimited()
&& $this->isSpam( $user['username'], $user['email'], $form->getValue('content') )
) {
$sender->message($this->message, 'warning');
$form->error('akismet', $this->message);
}
}

public function handler_conversationController_start($sender, $form)
{
if (!$form->validPostBack('content')) return;
$user = ET::$session->user;

if ( $this->userPostCountLimited()
&& $this->isSpam( $user['username'], $user['email'], $form->getValue('content') )
) {
$sender->message($this->message, 'warning');
$form->error('akismet', $this->message);
}
}


public function settings($sender)
{
$form = ETFactory::make('form');
$form->action = URL('admin/plugins/settings/Akismet');

$form->setValue('apiKey', C('plugin.akismet.apiKey'));
$form->setValue('userPostLimit', C('plugin.akismet.userPostLimit'));

if ($form->validPostBack('submit')) {
$config = array();
$config['plugin.akismet.apiKey'] = $form->getValue('apiKey');
$config['plugin.akismet.userPostLimit'] = $form->getValue('userPostLimit');

if (!$form->errorCount()) {
ET::writeConfig($config);
$sender->message(T('message.changesSaved'), 'success autoDismiss');
$sender->redirect(URL('admin/plugins'));
}
} elseif ($form->validPostBack('test')) {
$apiKey = $form->getValue('apiKey');

if ( $this->verifyKey($apiKey) ) {
$sender->message('verify key success', 'success autoDismiss');
} else {
$sender->message('verify key failed', 'warning autoDismiss');
}
return;
}

$sender->data('form', $form);
return $this->view('settings');
}


private function userPostCountLimited() {
// only check new users
$limit = C("plugin.akismet.userPostLimit");
if ( !is_numeric($limit) ) {
$limit = INF; // default always check
}

return $limit > ET::$session->user['countPosts'];
}

private function isSpam($author, $email, $content = '', $type = 'comment'/*registration*/, $info = null)
{
$apiKey = C('plugin.akismet.apiKey');
if (empty($apiKey)) return false; // skip if key not set

$url = 'http://' . $apiKey . '.rest.akismet.com/1.1/comment-check';

$headers = 'Content-type: application/x-www-form-urlencoded' . "\r\n"
. 'User-Agent: esoTalk/' . ESOTALK_VERSION . ' | Akismet/' . self::VERSION . "\r\n"
;

if ( is_null($info) ) {
$info = $_SERVER;
}

if ( !empty($_SERVER['HTTP_CLIENT_IP']) ) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif ( !empty($_SERVER['HTTP_X_FORWARDED_FOR']) ) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}

$body = array(
'blog' => C('esoTalk.baseURL'),
'user_ip' => $ip,
'user_agent' => $info['HTTP_USER_AGENT'],
'referrer' => $info['HTTP_REFERER'],
// 'permalink' => '',
'comment_type' => $type,
'comment_author' => $author,
'comment_author_email' => $email,
'comment_content' => $content,
);


$context = stream_context_create(array('http' => array(
'method' => 'POST',
'header' => $headers,
'content' => http_build_query($body),
)));

$result = file_get_contents($url, false, $context);

return $result === 'true';
}


private function verifyKey($key) {
$url = 'http://rest.akismet.com/1.1/verify-key';

$headers = 'Content-type: application/x-www-form-urlencoded' . "\r\n"
. 'User-Agent: esoTalk/' . ESOTALK_VERSION . ' | Akismet/' . self::VERSION . "\r\n"
;

$body = array(
'blog' => C('esoTalk.baseURL'),
'key' => $key,
);

$context = stream_context_create(array('http' => array(
'method' => 'POST',
'header' => $headers,
'content' => http_build_query($body),
)));

$result = file_get_contents($url, false, $context);

return $result === 'valid';
}
}
35 changes: 35 additions & 0 deletions addons/plugins/Akismet/views/settings.php
@@ -0,0 +1,35 @@
<?php
if (!defined("IN_ESOTALK")) exit;
$form = $data["form"];
?>

<?php echo $form->open(); ?>
<div class='section'>
<ul class='form'>
<li>
<label>API KEY</label>
<?php echo $form->input("apiKey", "text"); ?>
<small>请在<a href="https://akismet.com/" target="_blank">Akismet</a>申请API KEY</KEYgen></small>
</li>
<li>
<label>用户发帖最少限制</label>
<?php echo $form->input("userPostLimit", "number"); ?>
<small>只审查发帖数小于设置的用户(留空都审查)</small>
</li>
</ul>
</div>
<div class='buttons'>
<?php echo $form->saveButton("submit"); ?>
<button class='button big' type='button' onclick="akismetTestKey(this.form.apiKey.value)">测试</button>
</div>
<?php echo $form->close(); ?>

<script>
function akismetTestKey(key) {
$.ETAjax({
url: 'admin/plugins/settings.ajax/Akismet',
type: "post",
data: {apiKey: key, test: true}
});
}
</script>

0 comments on commit 9ee530a

Please sign in to comment.