mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-07 18:51:41 +09:00
스팸필터 애드온을 제거하고 스팸필터 모듈에서 직접 trigger로 글/댓글/스팸글에 대한 스팸필터링 제어. 엮인글 스팸필터링 기능 강화
git-svn-id: http://xe-core.googlecode.com/svn/sandbox@3216 201d5d3c-b55e-5fd7-737f-ddc643e51545
This commit is contained in:
parent
0729e06b31
commit
cb1e31bf5e
9 changed files with 272 additions and 140 deletions
|
|
@ -1,133 +1,6 @@
|
|||
<?php
|
||||
if(!defined("__ZBXE__")) exit();
|
||||
|
||||
/**
|
||||
* @file spamfilter.addon.php
|
||||
* @author zero (zero@nzeo.com)
|
||||
* @brief 스팸필터링 애드온
|
||||
*
|
||||
* 스팸필터 애드온은 SpamFilter 모듈을 이용합니다.
|
||||
* 글/코멘트/트랙백 등록 이전에만 실행이 됩니다.
|
||||
* 2007. 12. 7 스팸필터 모듈에서 trigger 기능으로 글/댓글/엮인글 처리하도록 하여 더 이상 사용하지 않도록 변경
|
||||
**/
|
||||
|
||||
// called_position가 before_module_proc 일때만 실행
|
||||
if($called_position != 'before_module_proc') return;
|
||||
|
||||
// 이 애드온이 동작할 대상 (이 부분은 특별히 정해진 규약이 없다)
|
||||
$effecived_target_act = array(
|
||||
'procBoardInsertDocument', 'procBoardInsertComment',
|
||||
'procBlogInsertComment',
|
||||
'trackback',
|
||||
);
|
||||
|
||||
// spam filter모듈이 적용될 module+act를 체크
|
||||
if(!in_array($this->act, $effecived_target_act)) return;
|
||||
|
||||
// 각 모듈별 act에 대해서도 피해갈 부분이 있으면 피해감
|
||||
switch($this->act) {
|
||||
|
||||
// 게시물 작성시 신규 등록이 아니면 패스~
|
||||
case 'procBoardInsertDocument' :
|
||||
// document module의 model 객체 생성
|
||||
$oDocumentModel = &getModel('document');
|
||||
|
||||
// 이미 존재하는 글인지 체크
|
||||
$document_srl = Context::get('document_srl');
|
||||
$oDocument = $oDocumentModel->getDocument($document_srl);
|
||||
|
||||
// 이미 존재하는 글이라면 return
|
||||
if($oDocument->isExists()) return;
|
||||
break;
|
||||
|
||||
// 댓글 작성시 신규 등록이 아니면 패스~
|
||||
case 'procBoardInsertComment' :
|
||||
case 'procBlogInsertComment' :
|
||||
$comment_srl = Context::get('comment_srl');
|
||||
$oCommentModel = &getModel('comment');
|
||||
|
||||
// 이미 존재하는 댓글인지 체크
|
||||
$comment = $oCommentModel->getComment($comment_srl);
|
||||
if($comment->comment_srl == $comment_srl) return;
|
||||
break;
|
||||
}
|
||||
|
||||
// 현재 모듈의 관리자이거나 그에 준하는 manager권한이면 그냥 패스
|
||||
if($this->grant->is_admin || $this->grant->manager) return;
|
||||
|
||||
// 현 접속자의 ip address를 구함
|
||||
$ipaddress = $_SERVER['REMOTE_ADDR'];
|
||||
|
||||
// spamfilter 모듈 객체 생성
|
||||
$oSpamFilterController = &getController('spamfilter');
|
||||
$oSpamFilterModel = &getModel('spamfilter');
|
||||
|
||||
// 스팸필터 기본 설정 출력
|
||||
$config = $oSpamFilterModel->getConfig();
|
||||
|
||||
// 스팸 간격을 체크하는 변수
|
||||
$interval = $config->interval?$config->interval:60;
|
||||
|
||||
// 스팸 간격내에 limit_count이상 작성을 시도하면 해당 ip를 금지 시킴
|
||||
$limit_count = $config->limit_count?$config->limit_count:5;
|
||||
|
||||
// 트랙백의 경우 한 글에 하나의 ip에서만 트랙백을 허용함
|
||||
$check_trackback = $config->check_trackback=='Y'?true:false;
|
||||
|
||||
// 스팸 IP에 등록되어 있는지 체크하여 등록되어 있으면 return
|
||||
$is_denied = $oSpamFilterModel->isDeniedIP($ipaddress);
|
||||
if($is_denied) {
|
||||
$output = new Object(-1, 'msg_alert_registered_denied_ip');
|
||||
$this->stop_proc = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// act==procReceiveTrackback (트랙백)일때 check_trackback==true이면 검사
|
||||
if($this->act=='trackback' && $check_trackback){
|
||||
$oTrackbackModel = &getModel('trackback');
|
||||
$document_srl = Context::get('document_srl');
|
||||
$count = $oTrackbackModel->getTrackbackCountByIPAddress($document_srl, $ipaddress);
|
||||
if($count>0) {
|
||||
$output = Object(-1, 'msg_alert_trackback_denied');
|
||||
$this->stop_proc = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 정해진 시간내에 글 작성 시도를 하였는지 체크
|
||||
$count = $oSpamFilterModel->getLogCount($interval, $ipaddress);
|
||||
|
||||
// 정해진 시간내에 정해진 글의 수를 초과시 스팸 IP로 등록시킴
|
||||
if($count>=$limit_count) {
|
||||
$oSpamFilterController->insertIP($ipaddress);
|
||||
$output = new Object(-1, 'msg_alert_registered_denied_ip');
|
||||
$this->stop_proc = true;
|
||||
return;
|
||||
|
||||
// 제한 글수까지는 아니지만 정해진 시간내에 글 작성을 계속 할때
|
||||
} elseif($count) {
|
||||
$message = sprintf(Context::getLang('msg_alert_limited_by_config'), $interval);
|
||||
$output = new Object(-1, $message);
|
||||
$this->stop_proc = true;
|
||||
}
|
||||
|
||||
// 금지 단어 체크를 위해서 몇가지 지정된 변수들을 한데 묶음
|
||||
$check_vars = implode("\n",get_object_vars(Context::getRequestVars()));
|
||||
|
||||
// 금지 단어를 이용하여 본문 내용을 체크
|
||||
$denied_word_list = $oSpamFilterModel->getDeniedWordList();
|
||||
$denied_word_count = count($denied_word_list);
|
||||
if($denied_word_count>0) {
|
||||
for($i=0;$i<$denied_word_count;$i++) {
|
||||
$word = preg_quote($denied_word_list[$i]->word,'/');
|
||||
if(preg_match('/'.$word.'/i', $check_vars)) {
|
||||
$message = sprintf(Context::getLang('msg_alert_denied_word'), $word);
|
||||
$output = new Object(-1, $message);
|
||||
$this->stop_proc = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 로그를 남김
|
||||
$oSpamFilterController->insertLog();
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,6 @@
|
|||
<column name="count(*)" alias="count" />
|
||||
</columns>
|
||||
<conditions>
|
||||
<condition operation="equal" column="ipaddress" var="ipaddress" notnull="notnull" />
|
||||
<condition operation="equal" column="ipaddress" default="ipaddress()" notnull="notnull" />
|
||||
</conditions>
|
||||
</query>
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@
|
|||
$oModuleController->insertActionForward('spamfilter', 'view', 'dispSpamfilterAdminDeniedIPList');
|
||||
$oModuleController->insertActionForward('spamfilter', 'view', 'dispSpamfilterAdminDeniedWordList');
|
||||
|
||||
// 2007. 12. 7 글/ 댓글/ 엮인글이 등록될때 스팸필터링을 시도하는 트리거
|
||||
$oModuleController->insertTrigger('document.insertDocument', 'spamfilter', 'controller', 'triggerInsertDocument', 'before');
|
||||
$oModuleController->insertTrigger('comment.insertComment', 'spamfilter', 'controller', 'triggerInsertComment', 'before');
|
||||
$oModuleController->insertTrigger('trackback.insertTrackback', 'spamfilter', 'controller', 'triggerInsertTrackback', 'before');
|
||||
|
||||
return new Object();
|
||||
}
|
||||
|
||||
|
|
@ -24,6 +29,13 @@
|
|||
* @brief 설치가 이상이 없는지 체크하는 method
|
||||
**/
|
||||
function checkUpdate() {
|
||||
$oModuleModel = &getModel('module');
|
||||
|
||||
// 2007. 12. 7 글/ 댓글/ 엮인글이 등록될때 스팸필터링을 시도하는 트리거
|
||||
if(!$oModuleModel->getTrigger('document.insertDocument', 'spamfilter', 'controller', 'triggerInsertDocument', 'before')) return true;
|
||||
if(!$oModuleModel->getTrigger('comment.insertComment', 'spamfilter', 'controller', 'triggerInsertComment', 'before')) return true;
|
||||
if(!$oModuleModel->getTrigger('trackback.insertTrackback', 'spamfilter', 'controller', 'triggerInsertTrackback', 'before')) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -31,7 +43,18 @@
|
|||
* @brief 업데이트 실행
|
||||
**/
|
||||
function moduleUpdate() {
|
||||
return new Object();
|
||||
$oModuleModel = &getModel('module');
|
||||
$oModuleController = &getController('module');
|
||||
|
||||
// 2007. 12. 7 글/ 댓글/ 엮인글이 등록될때 스팸필터링을 시도하는 트리거
|
||||
if(!$oModuleModel->getTrigger('document.insertDocument', 'spamfilter', 'controller', 'triggerInsertDocument', 'before'))
|
||||
$oModuleController->insertTrigger('document.insertDocument', 'spamfilter', 'controller', 'triggerInsertDocument', 'before');
|
||||
if(!$oModuleModel->getTrigger('comment.insertComment', 'spamfilter', 'controller', 'triggerInsertComment', 'before'))
|
||||
$oModuleController->insertTrigger('comment.insertComment', 'spamfilter', 'controller', 'triggerInsertComment', 'before');
|
||||
if(!$oModuleModel->getTrigger('trackback.insertTrackback', 'spamfilter', 'controller', 'triggerInsertTrackback', 'before'))
|
||||
$oModuleController->insertTrigger('trackback.insertTrackback', 'spamfilter', 'controller', 'triggerInsertTrackback', 'before');
|
||||
|
||||
return new Object(0,'success_updated');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -13,6 +13,112 @@
|
|||
function init() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 글 작성시 글 작성 시간 체크 및 금지 ip/단어 처리 루틴
|
||||
**/
|
||||
function triggerinsertDocument(&$obj) {
|
||||
// 로그인 여부, 로그인 정보, 권한 유무 체크
|
||||
$is_logged = Context::get('is_logged');
|
||||
$logged_info = Context::get('logged_info');
|
||||
$grant = Context::get('grant');
|
||||
|
||||
// 로그인 되어 있을 경우 관리자 여부를 체크
|
||||
if($is_logged) {
|
||||
if($logged_info->is_admin == 'Y') return new Object();
|
||||
if($grant->manager) return new Object();
|
||||
}
|
||||
|
||||
$oFilterModel = &getModel('spamfilter');
|
||||
|
||||
// ip가 금지되어 있는 경우를 체크
|
||||
$output = $oFilterModel->isDeniedIP();
|
||||
if(!$output->toBool()) return $output;
|
||||
|
||||
// 금지 단어에 있을 경우 체크
|
||||
$text = $obj->title.$obj->content;
|
||||
$output = $oFilterModel->isDeniedWord($text);
|
||||
if(!$output->toBool()) return $output;
|
||||
|
||||
// 지정된 시간 체크
|
||||
$output = $oFilterModel->checkLimited();
|
||||
if(!$output->toBool()) return $output;
|
||||
|
||||
// 로그 남김
|
||||
$this->insertLog();
|
||||
|
||||
return new Object();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 댓글 작성 시간 및 금지 ip/ 단어 처리 루틴
|
||||
**/
|
||||
function triggerInsertComment(&$obj) {
|
||||
// 로그인 여부, 로그인 정보, 권한 유무 체크
|
||||
$is_logged = Context::get('is_logged');
|
||||
$logged_info = Context::get('logged_info');
|
||||
$grant = Context::get('grant');
|
||||
|
||||
// 로그인 되어 있을 경우 관리자 여부를 체크
|
||||
if($is_logged) {
|
||||
if($logged_info->is_admin == 'Y') return new Object();
|
||||
if($grant->manager) return new Object();
|
||||
}
|
||||
|
||||
$oFilterModel = &getModel('spamfilter');
|
||||
|
||||
// ip가 금지되어 있는 경우를 체크
|
||||
$output = $oFilterModel->isDeniedIP();
|
||||
if(!$output->toBool()) return $output;
|
||||
|
||||
// 금지 단어에 있을 경우 체크
|
||||
$text = $obj->content;
|
||||
$output = $oFilterModel->isDeniedWord($text);
|
||||
if(!$output->toBool()) return $output;
|
||||
|
||||
// 지정된 시간 체크
|
||||
$output = $oFilterModel->checkLimited();
|
||||
if(!$output->toBool()) return $output;
|
||||
|
||||
// 로그 남김
|
||||
$this->insertLog();
|
||||
|
||||
return new Object();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 엮인글 작성시 시간 및 ip 검사
|
||||
**/
|
||||
function triggerInsertTrackback(&$obj) {
|
||||
$oFilterModel = &getModel('spamfilter');
|
||||
|
||||
// 해당 글에 엮인글을 한번 이상 추가하였는지를 확인
|
||||
$output = $oFilterModel->isInsertedTrackback($obj->document_srl);
|
||||
if(!$output->toBool()) return $output;
|
||||
|
||||
// ip가 금지되어 있는 경우를 체크
|
||||
$output = $oFilterModel->isDeniedIP();
|
||||
if(!$output->toBool()) return $output;
|
||||
|
||||
// 금지 단어에 있을 경우 체크
|
||||
$text = $obj->blog_name.$obj->title.$obj->excerpt.$obj->url;
|
||||
$output = $oFilterModel->isDeniedWord($text);
|
||||
if(!$output->toBool()) return $output;
|
||||
|
||||
// 12시간 이내에 3개 이상 한 C클래스의 ip에서 엮인글 등록 시도시 금지 아이피로 지정하고 해당 ip의 글을 모두 삭제
|
||||
$oTrackbackModel = &getModel('trackback');
|
||||
list($ipA,$ipB,$ipC,$ipD) = explode('.',$_SERVER['REMOTE_ADDR']);
|
||||
$ipaddress = $ipA.'.'.$ipB.'.'.$ipC;
|
||||
$count = $oTrackbackModel->getRegistedTrackback(24*60*60, $ipaddress);
|
||||
if($count > 2) {
|
||||
$oTrackbackController = &getController('trackback');
|
||||
$oTrackbackController->deleteTrackbackSender(24*60*60, $ipaddress);
|
||||
$this->insertIP($_SERVER['REMOTE_ADDR']);
|
||||
return new Object(-1,'msg_alert_trackback_denied');
|
||||
}
|
||||
|
||||
return new Object();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief IP 등록
|
||||
* 등록된 IP는 스패머로 간주
|
||||
|
|
|
|||
|
|
@ -37,11 +37,24 @@
|
|||
/**
|
||||
* @brief 인자로 넘겨진 ipaddress가 금지 ip인지 체크하여 return
|
||||
**/
|
||||
function isDeniedIP($ipaddress) {
|
||||
$args->ipaddress = $ipaddress;
|
||||
$output = executeQuery('spamfilter.isDeniedIP', $args);
|
||||
if($output->data->count>0) return true;
|
||||
return false;
|
||||
function isDeniedIP() {
|
||||
$ipaddress = $_SERVER['REMOTE_ADDR'];
|
||||
|
||||
$ip_list = $this->getDeniedIPList();
|
||||
if(!count($ip_list)) return false;
|
||||
|
||||
$count = count($ip_list);
|
||||
$patterns = array();
|
||||
for($i=0;$i<$count;$i++) {
|
||||
$ip = str_replace('*','',$ip_list[$i]->ipaddress);
|
||||
$patterns[] = $ip;
|
||||
}
|
||||
|
||||
$pattern = '/^('.implode($patterns,'|').')/';
|
||||
|
||||
if(preg_match($pattern, $ipaddress, $matches)) return new Object(-1,'msg_alert_registered_denied_ip');
|
||||
|
||||
return new Object();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -55,6 +68,69 @@
|
|||
return $output->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 넘어온 text에 금지 단어가 있는지 확인
|
||||
**/
|
||||
function isDeniedWord($text) {
|
||||
$word_list = $this->getDeniedWordList();
|
||||
if(!count($word_list)) return false;
|
||||
|
||||
$count = count($word_list);
|
||||
for($i=0;$i<$count;$i++) {
|
||||
$word = $word_list[$i]->word;
|
||||
if(strpos($text, $word)!==false) return new Object(-1,sprintf(Context::getLang('msg_alert_denied_word'), $word));
|
||||
}
|
||||
|
||||
return new Object();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 지정된 시간을 체크
|
||||
**/
|
||||
function checkLimited() {
|
||||
$config = $this->getConfig();
|
||||
$limit_count = $config->limit_count?$config->limit_count:5;
|
||||
$interval = $config->interval?$config->interval:60;
|
||||
|
||||
$count = $this->getLogCount($interval);
|
||||
|
||||
$ipaddress = $_SERVER['REMOTE_ADDR'];
|
||||
|
||||
// 정해진 시간보다 클 경우 금지 ip로 등록
|
||||
if($count>=$limit_count) {
|
||||
$oSpamFilterController = &getController('spamfilter');
|
||||
$oSpamFilterController->insertIP($ipaddress);
|
||||
return new Object(-1, 'msg_alert_registered_denied_ip');
|
||||
}
|
||||
|
||||
// 제한 글수까지는 아니지만 정해진 시간내에 글 작성을 계속 할때
|
||||
if($count) {
|
||||
$message = sprintf(Context::getLang('msg_alert_limited_by_config'), $interval);
|
||||
|
||||
$oSpamFilterController = &getController('spamfilter');
|
||||
$oSpamFilterController->insertLog();
|
||||
|
||||
return new Object(-1, $message);
|
||||
}
|
||||
|
||||
return new Object();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 특정 글에 이미 엮인글이 등록되어 있는지 확인
|
||||
**/
|
||||
function isInsertedTrackback($document_srl) {
|
||||
$config = $this->getConfig();
|
||||
$check_trackback = $config->check_trackback=='Y'?true:false;
|
||||
if(!$check_trackback) return new Object();
|
||||
|
||||
$oTrackbackModel = &getModel('trackback');
|
||||
$count = $oTrackbackModel->getTrackbackCountByIPAddress($document_srl, $_SERVER['REMOTE_ADDR']);
|
||||
if($count>0) return Object(-1, 'msg_alert_trackback_denied');
|
||||
|
||||
return new Object();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 지정된 IPaddress의 특정 시간대 내의 로그 수를 return
|
||||
**/
|
||||
|
|
|
|||
12
modules/trackback/queries/getRegistedTrackback.xml
Normal file
12
modules/trackback/queries/getRegistedTrackback.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<query id="getRegistedTrackback" action="select">
|
||||
<tables>
|
||||
<table name="trackbacks" />
|
||||
</tables>
|
||||
<columns>
|
||||
<column name="count(*)" alias="count" />
|
||||
</columns>
|
||||
<conditions>
|
||||
<condition operation="like_prefix" column="ipaddress" var="ipaddress" notnull="notnull" />
|
||||
<condition operation="more" column="regdate" var="regdate" notnull="notnull" pipe="and" />
|
||||
</conditions>
|
||||
</query>
|
||||
12
modules/trackback/queries/getRegistedTrackbacks.xml
Normal file
12
modules/trackback/queries/getRegistedTrackbacks.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<query id="getRegistedTrackbacks" action="select">
|
||||
<tables>
|
||||
<table name="trackbacks" />
|
||||
</tables>
|
||||
<columns>
|
||||
<column name="*" />
|
||||
</columns>
|
||||
<conditions>
|
||||
<condition operation="like_prefix" column="ipaddress" var="ipaddress" notnull="notnull" />
|
||||
<condition operation="more" column="regdate" var="regdate" notnull="notnull" pipe="and" />
|
||||
</conditions>
|
||||
</query>
|
||||
|
|
@ -114,6 +114,15 @@
|
|||
}
|
||||
|
||||
function insertTrackback($obj, $manual_inserted = false) {
|
||||
// 엮인글 정리
|
||||
$obj = Context::convertEncoding($obj);
|
||||
if(!$obj->blog_name) $obj->blog_name = $obj->title;
|
||||
$obj->excerpt = strip_tags($obj->excerpt);
|
||||
|
||||
// trigger 호출 (before)
|
||||
$output = ModuleHandler::triggerCall('trackback.insertTrackback', 'before', $obj);
|
||||
if(!$output->toBool()) return $output;
|
||||
|
||||
// GET으로 넘어온 document_srl을 참조, 없으면 오류~
|
||||
$document_srl = $obj->document_srl;
|
||||
|
||||
|
|
@ -129,10 +138,6 @@
|
|||
$obj->module_srl = $oDocument->get('module_srl');
|
||||
}
|
||||
|
||||
// 엮인글 정리
|
||||
$obj = Context::convertEncoding($obj);
|
||||
if(!$obj->blog_name) $obj->blog_name = $obj->title;
|
||||
$obj->excerpt = strip_tags($obj->excerpt);
|
||||
|
||||
// 엮인글를 입력
|
||||
$obj->trackback_srl = getNextSequence();
|
||||
|
|
@ -283,5 +288,20 @@
|
|||
|
||||
return new Object(0, 'msg_trackback_send_success');
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 특정 ipaddress의 특정 시간대 내의 엮인글을 모두 삭제
|
||||
**/
|
||||
function deleteTrackbackSender($time, $ipaddress) {
|
||||
$obj->regdate = date("YmdHis",time()-$time);
|
||||
$obj->ipaddress = $ipaddress;
|
||||
$output = executeQueryArray('trackback.getRegistedTrackbacks', $obj);
|
||||
if(!$output->data || !count($output->data)) return;
|
||||
|
||||
foreach($output->data as $trackback) {
|
||||
$trackback_srl = $trackback->trackback_srl;
|
||||
$this->deleteTrackback($trackback_srl, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -97,5 +97,15 @@
|
|||
}
|
||||
return $module_trackback_config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 정해진 시간내에 전체 엮인글 등록수를 구함
|
||||
**/
|
||||
function getRegistedTrackback($time, $ipaddress) {
|
||||
$obj->regdate = date("YmdHis",time()-$time);
|
||||
$obj->ipaddress = $ipaddress;
|
||||
$output = executeQuery('trackback.getRegistedTrackback', $obj);
|
||||
return $output->data->count;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue