Dotclear

source: plugins/antispam/filters/class.dc.filter.ip.php @ 2205:4d5c86bc51e9

Revision 2205:4d5c86bc51e9, 7.7 KB checked in by franck <carnet.franck.paul@…>, 12 years ago (diff)

Add success messages using the new notices system. Closes #1494, #1495

Line 
1<?php
2# -- BEGIN LICENSE BLOCK ---------------------------------------
3#
4# This file is part of Antispam, a plugin for Dotclear 2.
5#
6# Copyright (c) 2003-2013 Olivier Meunier & Association Dotclear
7# Licensed under the GPL version 2.0 license.
8# See LICENSE file or
9# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10#
11# -- END LICENSE BLOCK -----------------------------------------
12if (!defined('DC_RC_PATH')) { return; }
13
14class dcFilterIP extends dcSpamFilter
15{
16     public $name = 'IP Filter';
17     public $has_gui = true;
18
19     private $con;
20     private $table;
21
22     public function __construct($core)
23     {
24          parent::__construct($core);
25          $this->con =& $core->con;
26          $this->table = $core->prefix.'spamrule';
27     }
28
29     protected function setInfo()
30     {
31          $this->description = __('IP Blacklist / Whitelist Filter');
32     }
33
34     public function getStatusMessage($status,$comment_id)
35     {
36          return sprintf(__('Filtered by %1$s with rule %2$s.'),$this->guiLink(),$status);
37     }
38
39     public function isSpam($type,$author,$email,$site,$ip,$content,$post_id,&$status)
40     {
41          if (!$ip) {
42               return;
43          }
44
45          # White list check
46          if ($this->checkIP($ip,'white') !== false) {
47               return false;
48          }
49
50          # Black list check
51          if (($s = $this->checkIP($ip,'black')) !== false) {
52               $status = $s;
53               return true;
54          }
55     }
56
57     public function gui($url)
58     {
59          global $default_tab;
60          $core =& $this->core;
61
62          # Set current type and tab
63          $ip_type = 'black';
64          if (!empty($_REQUEST['ip_type']) && $_REQUEST['ip_type'] == 'white') {
65               $ip_type = 'white';
66          }
67          $default_tab = 'tab_'.$ip_type;
68
69          # Add IP to list
70          if (!empty($_POST['addip']))
71          {
72               try
73               {
74                    $global = !empty($_POST['globalip']) && $core->auth->isSuperAdmin();
75
76                    $this->addIP($ip_type,$_POST['addip'],$global);
77                    dcPage::addSuccessNotice(__('IP address has been successfully added.'));
78                    http::redirect($url.'&ip_type='.$ip_type);
79               }
80               catch (Exception $e)
81               {
82                    $core->error->add($e->getMessage());
83               }
84          }
85
86          # Remove IP from list
87          if (!empty($_POST['delip']) && is_array($_POST['delip']))
88          {
89               try {
90                    $this->removeRule($_POST['delip']);
91                    dcPage::addSuccessNotice(__('IP addresses have been successfully removed.'));
92                    http::redirect($url.'&ip_type='.$ip_type);
93               } catch (Exception $e) {
94                    $core->error->add($e->getMessage());
95               }
96          }
97
98          /* DISPLAY
99          ---------------------------------------------- */
100          $res = dcPage::notices();
101
102          $res .=
103          $this->displayForms($url,'black',__('Blacklist')).
104          $this->displayForms($url,'white',__('Whitelist'));
105
106          return $res;
107     }
108
109     private function displayForms($url,$type,$title)
110     {
111          $core =& $this->core;
112
113          $res =
114          '<div class="multi-part" id="tab_'.$type.'" title="'.$title.'">'.
115
116          '<form action="'.html::escapeURL($url).'" method="post" class="fieldset">'.
117
118          '<p>'.
119          form::hidden(array('ip_type'),$type).
120          '<label class="classic" for="addip_'.$type.'">'.__('Add an IP address: ').'</label> '.
121          form::field(array('addip', 'addip_'.$type),18,255);
122               if ($core->auth->isSuperAdmin()) {
123                    $res .= '<label class="classic" for="globalip_'.$type.'">'.form::checkbox(array('globalip', 'globalip_'.$type),1).' '.
124                    __('Global IP (used for all blogs)').'</label> ';
125               }
126
127          $res .=
128          $core->formNonce().
129          '</p>'.
130          '<p><input type="submit" value="'.__('Add').'"/></p>'.
131          '</form>';
132
133          $rs = $this->getRules($type);
134
135          if ($rs->isEmpty())
136          {
137               $res .= '<p><strong>'.__('No IP address in list.').'</strong></p>';
138          }
139          else
140          {
141               $res .=
142               '<form action="'.html::escapeURL($url).'" method="post">'.
143               '<h3>' . __('IP list') . '</h3>'.
144               '<div class="antispam">';
145
146               $res_global = '';
147               $res_local = '';
148               while ($rs->fetch())
149               {
150                    $bits = explode(':',$rs->rule_content);
151                    $pattern = $bits[0];
152                    $ip = $bits[1];
153                    $bitmask = $bits[2];
154
155                    $disabled_ip = false;
156                    $p_style = '';
157                    if (!$rs->blog_id) {
158                         $disabled_ip = !$core->auth->isSuperAdmin();
159                         $p_style .= ' global';
160                    }
161
162                    $item =
163                    '<p class="'.$p_style.'"><label class="classic" for="'.$type.'-ip-'.$rs->rule_id.'">'.
164                    form::checkbox(array('delip[]',$type.'-ip-'.$rs->rule_id),$rs->rule_id,false,'','',$disabled_ip).' '.
165                    html::escapeHTML($pattern).
166                    '</label></p>';
167
168                    if ($rs->blog_id) {
169                         // local list
170                         if ($res_local == '') {
171                              $res_local = '<h4>'.__('Local IPs (used only for this blog)').'</h4>';
172                         }
173                         $res_local .= $item;
174                    } else {
175                         // global list
176                         if ($res_global == '') {
177                              $res_global = '<h4>'.__('Global IPs (used for all blogs)').'</h4>';
178                         }
179                         $res_global .= $item;
180                    }
181               }
182               $res .= $res_local.$res_global;
183
184               $res .=
185               '</div>'.
186               '<p><input class="submit delete" type="submit" value="'.__('Delete').'"/>'.
187               $core->formNonce().
188               form::hidden(array('ip_type'),$type).
189               '</p>'.
190               '</form>';
191          }
192
193          $res .= '</div>';
194
195          return $res;
196     }
197
198     private function ipmask($pattern,&$ip,&$mask)
199     {
200          $bits = explode('/',$pattern);
201
202          # Set IP
203          $bits[0] .= str_repeat(".0", 3 - substr_count($bits[0], "."));
204          $ip = ip2long($bits[0]);
205
206          if (!$ip || $ip == -1) {
207               throw new Exception('Invalid IP address');
208          }
209
210          # Set mask
211          if (!isset($bits[1])) {
212               $mask = -1;
213          } elseif (strpos($bits[1],'.')) {
214               $mask = ip2long($bits[1]);
215               if (!$mask) {
216                    $mask = -1;
217               }
218          } else {
219               $mask = ~((1 << (32 - $bits[1])) - 1);
220          }
221     }
222
223     private function addIP($type,$pattern,$global)
224     {
225          $this->ipmask($pattern,$ip,$mask);
226          $pattern = long2ip($ip).($mask != -1 ? '/'.long2ip($mask) : '');
227          $content = $pattern.':'.$ip.':'.$mask;
228
229          $old = $this->getRuleCIDR($type,$global,$ip,$mask);
230          $cur = $this->con->openCursor($this->table);
231
232          if ($old->isEmpty())
233          {
234               $id = $this->con->select('SELECT MAX(rule_id) FROM '.$this->table)->f(0) + 1;
235
236               $cur->rule_id = $id;
237               $cur->rule_type = (string) $type;
238               $cur->rule_content = (string) $content;
239
240               if ($global && $this->core->auth->isSuperAdmin()) {
241                    $cur->blog_id = null;
242               } else {
243                    $cur->blog_id = $this->core->blog->id;
244               }
245
246               $cur->insert();
247          }
248          else
249          {
250               $cur->rule_type = (string) $type;
251               $cur->rule_content = (string) $content;
252               $cur->update('WHERE rule_id = '.(integer) $old->rule_id);
253          }
254     }
255
256     private function getRules($type='all')
257     {
258          $strReq =
259          'SELECT rule_id, rule_type, blog_id, rule_content '.
260          'FROM '.$this->table.' '.
261          "WHERE rule_type = '".$this->con->escape($type)."' ".
262          "AND (blog_id = '".$this->core->blog->id."' OR blog_id IS NULL) ".
263          'ORDER BY blog_id ASC, rule_content ASC ';
264
265          return $this->con->select($strReq);
266     }
267
268     private function getRuleCIDR($type,$global,$ip,$mask)
269     {
270          $strReq =
271          'SELECT * FROM '.$this->table.' '.
272          "WHERE rule_type = '".$this->con->escape($type)."' ".
273          "AND rule_content LIKE '%:".(integer) $ip.":".(integer) $mask."' ".
274          'AND blog_id '.($global ? 'IS NULL ' : "= '".$this->core->blog->id."' ");
275
276          return $this->con->select($strReq);
277     }
278
279     private function checkIP($cip,$type)
280     {
281          $core =& $this->core;
282
283          $strReq =
284          'SELECT DISTINCT(rule_content) '.
285          'FROM '.$this->table.' '.
286          "WHERE rule_type = '".$this->con->escape($type)."' ".
287          "AND (blog_id = '".$this->core->blog->id."' OR blog_id IS NULL) ".
288          'ORDER BY rule_content ASC ';
289
290          $rs = $this->con->select($strReq);
291          while ($rs->fetch())
292          {
293               list($pattern,$ip,$mask) = explode(':',$rs->rule_content);
294               if ((ip2long($cip) & (integer) $mask) == ((integer) $ip & (integer) $mask)) {
295                    return $pattern;
296               }
297          }
298          return false;
299     }
300
301     private function removeRule($ids)
302     {
303          $strReq = 'DELETE FROM '.$this->table.' ';
304
305          if (is_array($ids)) {
306               foreach ($ids as $i => $v) {
307                    $ids[$i] = (integer) $v;
308               }
309               $strReq .= 'WHERE rule_id IN ('.implode(',',$ids).') ';
310          } else {
311               $ids = (integer) $ids;
312               $strReq .= 'WHERE rule_id = '.$ids.' ';
313          }
314
315          if (!$this->core->auth->isSuperAdmin()) {
316               $strReq .= "AND blog_id = '".$this->core->blog->id."' ";
317          }
318
319          $this->con->execute($strReq);
320     }
321}
322?>
Note: See TracBrowser for help on using the repository browser.

Sites map