Просмотр исходного кода

Ticket #4603 - Antispam: Integrate Lasso Moderation API.

AntonLV 2 лет назад
Родитель
Сommit
77584d5781

+ 23 - 0
modules/base/general/classes/BxBaseModGeneralModule.php

@@ -173,6 +173,29 @@ class BxBaseModGeneralModule extends BxDolModule
         }
     }
 
+    public function serviceSetStatus($iId, $sValue, $sStatus = '')
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!$sStatus && !empty($CNF['FIELD_STATUS_ADMIN']))
+            $sStatus = $CNF['FIELD_STATUS_ADMIN'];
+
+        $aStatuses = [];
+        if(!empty($CNF['FIELD_STATUS_ADMIN']))
+            $aStatuses[] = $CNF['FIELD_STATUS_ADMIN'];
+        if(!empty($CNF['FIELD_STATUS']))
+            $aStatuses[] = $CNF['FIELD_STATUS'];
+
+        if(!in_array($sStatus, $aStatuses))
+            return false;
+
+        if((int)$this->_oDb->updateEntriesBy([$sStatus => $sValue], [$CNF['FIELD_ID'] => $iId]) == 0)
+            return false;
+
+        if($sValue == BX_BASE_MOD_GENERAL_STATUS_ACTIVE)
+            $this->onPublished($iId);
+    }
+
     public function actionRss ()
     {
         $aArgs = func_get_args();

+ 11 - 2
modules/boonex/antispam/classes/BxAntispamConfig.php

@@ -30,9 +30,13 @@ class BxAntispamConfig extends BxDolModuleConfig
         'toxicity_report' => 'bx_antispam_toxicity_filter_report',
         'lm_enable' => 'bx_antispam_lasso_moderation_enable',
         'lm_api_key' => 'bx_antispam_lasso_moderation_api_key',
-        'lm_webhook_secret' => 'lasso_moderation_webhook_secret',
+        'lm_webhook_secret' => 'bx_antispam_lasso_moderation_webhook_secret',
         'lm_action' => 'bx_antispam_lasso_moderation_action',
         'lm_report' => 'bx_antispam_lasso_moderation_report',
+        'lm_thd_toxicity' => 'bx_antispam_lasso_moderation_threshold_toxicity',
+        'lm_thd_threat' => 'bx_antispam_lasso_moderation_threshold_threat',
+        'lm_thd_identity_attack' => 'bx_antispam_lasso_moderation_threshold_identity_attack',
+        'lm_thd_profanity' => 'bx_antispam_lasso_moderation_threshold_profanity',
     );
     /**
      * default local options, it is filled in with real system options in class contructor, @see restoreAntispamOptions
@@ -51,8 +55,13 @@ class BxAntispamConfig extends BxDolModuleConfig
         'toxicity_report' => '',
         'lm_enable' => '',
         'lm_api_key' => '',
+        'lm_webhook_secret' => '',
         'lm_action' => '',
-        'lm_report' => ''
+        'lm_report' => '',
+        'lm_thd_toxicity' => '',
+        'lm_thd_threat' => '',
+        'lm_thd_identity_attack' => '',
+        'lm_thd_profanity' => '',
     );
 
     public function __construct($aModule)

+ 111 - 10
modules/boonex/antispam/classes/BxAntispamLassoModeration.php

@@ -14,9 +14,13 @@ class BxAntispamLassoModeration extends BxDol
     protected $_sModule;
     protected $_oModule;
 
+    protected $_sEndpoint;
+
     protected $_sApiKey;
     protected $_sWebhookSecret;
-    protected $_sEndpoint;
+    protected $_sAction;
+    protected $_bNotify;
+    protected $_aThresholds;
 
     public function __construct()
     {
@@ -25,32 +29,129 @@ class BxAntispamLassoModeration extends BxDol
         $this->_sModule = 'bx_antispam';
         $this->_oModule = BxDolModule::getInstance($this->_sModule);
 
+        $this->_sEndpoint = 'https://api.lassomoderation.com/api/v1';
+
         $this->_sApiKey = $this->_oModule->_oConfig->getAntispamOption('lm_api_key');
         $this->_sWebhookSecret = $this->_oModule->_oConfig->getAntispamOption('lm_webhook_secret');
-
-        $this->_sEndpoint = 'https://api.lassomoderation.com/api/v1';
+        $this->_sAction = $this->_oModule->_oConfig->getAntispamOption('lm_action');
+        $this->_bNotify = $this->_oModule->_oConfig->getAntispamOption('lm_report') == 'on';
+        $this->_aThresholds = [
+            'toxicity' => (int)$this->_oModule->_oConfig->getAntispamOption('lm_thd_toxicity'),
+            'threat' => (int)$this->_oModule->_oConfig->getAntispamOption('lm_thd_threat'),
+            'identity_attack' => (int)$this->_oModule->_oConfig->getAntispamOption('lm_thd_identity_attack'),
+            'profanity' => (int)$this->_oModule->_oConfig->getAntispamOption('lm_thd_profanity')
+        ];
     }
 
     public function processEvent()
     {
         $sInput = @file_get_contents("php://input");
-        
+        if(!$sInput)
+            return 200;
+
+        $aHeaders = getallheaders();
+        if(empty($aHeaders['X-Lasso-Signature'])) {
+            $this->log($sInput, 'Webhook: Cannot get Signature.');
+            return 404;
+        }
+
         $sInputHmac = hash_hmac('sha256', $sInput, $this->_sWebhookSecret, true);
         $sInputHmac = 'sha256=' . base64_encode($sInputHmac);
-        
-        if($sInputHmac !== '')
+        if($sInputHmac !== $aHeaders['X-Lasso-Signature']) {
+            $this->log($sInput, 'Webhook: Wrong Signature.');
+            $this->log([
+                'secret' => $this->_sWebhookSecret,
+                'sig_get' => $aHeaders['X-Lasso-Signature'],
+                'sig_calc' => $sInputHmac
+            ]);
+
             return 404;
-        
+        }
+
         $aEvent = json_decode($sInput, true);
-        if(empty($aEvent) || !is_array($aEvent)) 
+        if(empty($aEvent) || !is_array($aEvent) || !isset($aEvent['actions'])) {
+            $this->log($sInput, 'Webhook: Wrong input data.');
             return 404;
+        }
+
+        foreach($aEvent['actions'] as $aAction) {
+            $sMethod = '_processEvent' . bx_gen_method_name($aAction['type']);
+            if(!method_exists($this, $sMethod))
+                continue;
+
+            $sModule = '';
+            $iContentId = 0;
+            switch($aAction['type']) {
+                case 'user':
+                    break;
 
-        //TODO: Do something here.
+                case 'topic':
+                    break;
 
-        //$this->_onHarmfulContentFound();
+                case 'content':
+                    $iContentId = $this->_getId($aAction['content']['id']);
+                    $iModuleId = $this->_getId($aAction['content']['topic_id']);
+                    if(!$iContentId || !$iModuleId)
+                        break;
+
+                    $aModule = $this->_oModule->_oDb->getModuleById($iModuleId);
+                    if(empty($aModule) || !is_array($aModule))
+                        break;
+                    
+                    $sModule = $aModule['name'];
+                    
+                    $this->$sMethod($sModule, $iContentId, $aAction['status'], $aAction['content']['analysis']);
+                    break;
+            }
+
+            if($bNotify && $sModule != '' && $iContentId != 0)
+                $this->_onHarmfulContentFound($sModule, $iContentId);
+        }
 
         return 200;
     }
+    
+    protected function _getId($s)
+    {
+        return (int)substr($s, strrpos($s, '_') + 1);
+    }
+
+    protected function _processEventContent($sModule, $iContentId, $sStatus, $aAnalysis)
+    {
+        $sFldStatus = 'status_admin';
+
+        $aContentInfo = bx_srv($sModule, 'get_info', [$iContentId, false]);
+        if(!isset($aContentInfo[$sFldStatus]))
+            return;
+
+        $sStatus = '';
+        switch($sStatus) {
+            case 'allowed':
+                if($aContentInfo[$sFldStatus] != 'active')
+                    $sStatus = 'active';
+                break;
+
+            case 'hidden':
+                if($aContentInfo[$sFldStatus] != 'hidden' && $this->_sAction == 'disapprove')
+                    $sStatus = 'hidden';
+                break;
+
+            case 'flagged':
+                foreach($this->_aThresholds as $sName => $iThreshold) {
+                    if(100 * $aAnalysis[$sName] < $iThreshold) 
+                        continue;
+
+                    if($aContentInfo[$sFldStatus] != 'hidden' && $this->_sAction == 'disapprove') {
+                        $sStatus = 'hidden';
+                        break;
+                    }
+                }
+                break;
+        }
+
+        if(!empty($sStatus))
+            bx_srv($sModule, 'set_status', [$iContentId, $sStatus, $sFldStatus]);
+    }
 
     public function addContent($sModule, $iId, $aData = [])
     {

+ 4 - 0
modules/boonex/antispam/install/langs/en.xml

@@ -215,6 +215,10 @@ This antispam method scan submitted content for the URLs and check them if any o
     <string name="_bx_antispam_option_lasso_moderation_action_none"><![CDATA[None]]></string>
     <string name="_bx_antispam_option_lasso_moderation_action_disapprove"><![CDATA[Disapprove]]></string>
     <string name="_bx_antispam_option_lasso_moderation_report"><![CDATA[Send report to admin if harmful content discovered]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_threshold_toxicity"><![CDATA[Toxicity threshold (0 - 100)]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_threshold_threat"><![CDATA[Threat threshold (0 - 100)]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_threshold_identity_attack"><![CDATA[Identity attack threshold (0 - 100)]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_threshold_profanity"><![CDATA[Profanity threshold (0 - 100)]]></string>
     <string name="_bx_antispam_et_lasso_moderation_report_name"><![CDATA[Harmful content posted report message]]></string>
     <string name="_bx_antispam_et_lasso_moderation_report_subject"><![CDATA[Harmful content has been posted]]></string>
     <string name="_bx_antispam_et_lasso_moderation_report_body"><![CDATA[{email_header}

+ 5 - 1
modules/boonex/antispam/install/sql/enable.sql

@@ -100,7 +100,11 @@ INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `ex
 (@iCategoryId, 'bx_antispam_lasso_moderation_webhook_secret', '_bx_antispam_option_lasso_moderation_webhook_secret', '', 'digit', '', '', '', 30),
 (@iCategoryId, 'bx_antispam_lasso_moderation_webhook_url', '_bx_antispam_option_lasso_moderation_webhook_url', '{site_url}m/antispam/content_checked', 'value', '', '', '', 40),
 (@iCategoryId, 'bx_antispam_lasso_moderation_action', '_bx_antispam_option_lasso_moderation_action', 'none', 'select', 'a:2:{s:6:"module";s:11:"bx_antispam";s:6:"method";s:28:"get_lasso_moderation_actions";}', '', '', 50),
-(@iCategoryId, 'bx_antispam_lasso_moderation_report', '_bx_antispam_option_lasso_moderation_report', '', 'checkbox', 'on', '', '', 60);
+(@iCategoryId, 'bx_antispam_lasso_moderation_report', '_bx_antispam_option_lasso_moderation_report', '', 'checkbox', 'on', '', '', 60),
+(@iCategoryId, 'bx_antispam_lasso_moderation_threshold_toxicity', '_bx_antispam_option_lasso_moderation_threshold_toxicity', '50', 'digit', '', '', '', 70),
+(@iCategoryId, 'bx_antispam_lasso_moderation_threshold_threat', '_bx_antispam_option_lasso_moderation_threshold_threat', '50', 'digit', '', '', '', 72),
+(@iCategoryId, 'bx_antispam_lasso_moderation_threshold_identity_attack', '_bx_antispam_option_lasso_moderation_threshold_identity_attack', '50', 'digit', '', '', '', 74),
+(@iCategoryId, 'bx_antispam_lasso_moderation_threshold_profanity', '_bx_antispam_option_lasso_moderation_threshold_profanity', '50', 'digit', '', '', '', 76);
 
 -- page: DNSBL list
 

+ 4 - 0
modules/boonex/russian/data/langs/bx_antispam/ru.xml

@@ -216,6 +216,10 @@ URI DNSBL - это DNSBL, которые перечисляют доменные
     <string name="_bx_antispam_option_lasso_moderation_action_none"><![CDATA[Нет]]></string>
     <string name="_bx_antispam_option_lasso_moderation_action_disapprove"><![CDATA[Скрывать]]></string>
     <string name="_bx_antispam_option_lasso_moderation_report"><![CDATA[Отправлять администратору уведомление о вредоносном контенте]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_threshold_toxicity"><![CDATA[Порог токсичности (0 - 100)]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_threshold_threat"><![CDATA[Порог угрозы (0 - 100)]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_threshold_identity_attack"><![CDATA[Порог атаки на личность (0 - 100)]]></string>
+    <string name="_bx_antispam_option_lasso_moderation_threshold_profanity"><![CDATA[Порог ненормативной лексики (0 - 100)]]></string>
     <string name="_bx_antispam_et_lasso_moderation_report_name"><![CDATA[Сообщение о размещенном вредоносном контенте]]></string>
     <string name="_bx_antispam_et_lasso_moderation_report_subject"><![CDATA[Размещен вредоносный контент]]></string>
     <string name="_bx_antispam_et_lasso_moderation_report_body"><![CDATA[{email_header}