]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/Blacklist/BlacklistPlugin.php
Blacklist admin panel
[quix0rs-gnu-social.git] / plugins / Blacklist / BlacklistPlugin.php
1 <?php
2 /**
3  * StatusNet, the distributed open-source microblogging tool
4  *
5  * Plugin to prevent use of nicknames or URLs on a blacklist
6  *
7  * PHP version 5
8  *
9  * LICENCE: This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU Affero General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Affero General Public License for more details.
18  *
19  * You should have received a copy of the GNU Affero General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  * @category  Action
23  * @package   StatusNet
24  * @author    Evan Prodromou <evan@status.net>
25  * @copyright 2010 StatusNet Inc.
26  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
27  * @link      http://status.net/
28  */
29
30 if (!defined('STATUSNET')) {
31     exit(1);
32 }
33
34 /**
35  * Plugin to prevent use of nicknames or URLs on a blacklist
36  *
37  * @category Plugin
38  * @package  StatusNet
39  * @author   Evan Prodromou <evan@status.net>
40  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
41  * @link     http://status.net/
42  */
43
44 class BlacklistPlugin extends Plugin
45 {
46     const VERSION = STATUSNET_VERSION;
47
48     public $nicknames = array();
49     public $urls      = array();
50     public $canAdmin  = true;
51
52     private $_nicknamePatterns = array();
53     private $_urlPatterns      = array();
54
55     /**
56      * Initialize the plugin
57      *
58      * @return void
59      */
60
61     function initialize()
62     {
63         $confNicknames = $this->_configArray('blacklist', 'nicknames')
64
65         $this->_nicknamePatterns = array_merge($this->nicknames,
66                                                $confNicknames);
67
68         $confURLs = $this->_configArray('blacklist', 'urls')
69
70         $this->_urlPatterns = array_merge($this->urls,
71                                           $confURLs);
72     }
73
74     /**
75      * Retrieve an array from configuration
76      *
77      * Carefully checks a section.
78      *
79      * @param string $section Configuration section
80      * @param string $setting Configuration setting
81      *
82      * @return array configuration values
83      */
84
85     function _configArray($section, $setting)
86     {
87         $config = common_config($section, $setting);
88
89         if (empty($config)) {
90             return array();
91         } else if (is_array($config)) {
92             return $config;
93         } else if (is_string($config)) {
94             return explode("\r\n", $config);
95         } else {
96             throw new Exception("Unknown data type for config $section + $setting");
97         }
98     }
99
100     /**
101      * Hook registration to prevent blacklisted homepages or nicknames
102      *
103      * Throws an exception if there's a blacklisted homepage or nickname.
104      *
105      * @param Action $action Action being called (usually register)
106      *
107      * @return boolean hook value
108      */
109
110     function onStartRegistrationTry($action)
111     {
112         $homepage = strtolower($action->trimmed('homepage'));
113
114         if (!empty($homepage)) {
115             if (!$this->_checkUrl($homepage)) {
116                 $msg = sprintf(_m("You may not register with homepage '%s'"),
117                                $homepage);
118                 throw new ClientException($msg);
119             }
120         }
121
122         $nickname = strtolower($action->trimmed('nickname'));
123
124         if (!empty($nickname)) {
125             if (!$this->_checkNickname($nickname)) {
126                 $msg = sprintf(_m("You may not register with nickname '%s'"),
127                                $nickname);
128                 throw new ClientException($msg);
129             }
130         }
131
132         return true;
133     }
134
135     /**
136      * Hook profile update to prevent blacklisted homepages or nicknames
137      *
138      * Throws an exception if there's a blacklisted homepage or nickname.
139      *
140      * @param Action $action Action being called (usually register)
141      *
142      * @return boolean hook value
143      */
144
145     function onStartProfileSaveForm($action)
146     {
147         $homepage = strtolower($action->trimmed('homepage'));
148
149         if (!empty($homepage)) {
150             if (!$this->_checkUrl($homepage)) {
151                 $msg = sprintf(_m("You may not use homepage '%s'"),
152                                $homepage);
153                 throw new ClientException($msg);
154             }
155         }
156
157         $nickname = strtolower($action->trimmed('nickname'));
158
159         if (!empty($nickname)) {
160             if (!$this->_checkNickname($nickname)) {
161                 $msg = sprintf(_m("You may not use nickname '%s'"),
162                                $nickname);
163                 throw new ClientException($msg);
164             }
165         }
166
167         return true;
168     }
169
170     /**
171      * Hook notice save to prevent blacklisted urls
172      *
173      * Throws an exception if there's a blacklisted url in the content.
174      *
175      * @param Notice &$notice Notice being saved
176      *
177      * @return boolean hook value
178      */
179
180     function onStartNoticeSave(&$notice)
181     {
182         common_replace_urls_callback($notice->content,
183                                      array($this, 'checkNoticeUrl'));
184         return true;
185     }
186
187     /**
188      * Helper callback for notice save
189      *
190      * Throws an exception if there's a blacklisted url in the content.
191      *
192      * @param string $url URL in the notice content
193      *
194      * @return boolean hook value
195      */
196
197     function checkNoticeUrl($url)
198     {
199         // It comes in special'd, so we unspecial it
200         // before comparing against patterns
201
202         $url = htmlspecialchars_decode($url);
203
204         if (!$this->_checkUrl($url)) {
205             $msg = sprintf(_m("You may not use url '%s' in notices"),
206                            $url);
207             throw new ClientException($msg);
208         }
209
210         return $url;
211     }
212
213     /**
214      * Helper for checking URLs
215      *
216      * Checks an URL against our patterns for a match.
217      *
218      * @param string $url URL to check
219      *
220      * @return boolean true means it's OK, false means it's bad
221      */
222
223     private function _checkUrl($url)
224     {
225         foreach ($this->_urlPatterns as $pattern) {
226             common_debug("Checking $url against $pattern");
227             if (preg_match("/$pattern/", $url)) {
228                 return false;
229             }
230         }
231
232         return true;
233     }
234
235     /**
236      * Helper for checking nicknames
237      *
238      * Checks a nickname against our patterns for a match.
239      *
240      * @param string $nickname nickname to check
241      *
242      * @return boolean true means it's OK, false means it's bad
243      */
244
245     private function _checkNickname($nickname)
246     {
247         foreach ($this->_nicknamePatterns as $pattern) {
248             common_debug("Checking $nickname against $pattern");
249             if (preg_match("/$pattern/", $nickname)) {
250                 return false;
251             }
252         }
253
254         return true;
255     }
256
257     /**
258      * Add our actions to the URL router
259      *
260      * @param Net_URL_Mapper $m URL mapper for this hit
261      *
262      * @return boolean hook return
263      */
264
265     function onRouterInitialized($m)
266     {
267         $m->connect('admin/blacklist', array('action' => 'blacklistadminpanel'));
268         return true;
269     }
270
271     /**
272      * Auto-load our classes if called
273      *
274      * @param string $cls Class to load
275      *
276      * @return boolean hook return
277      */
278
279     function onAutoload($cls)
280     {
281         switch (strtolower($cls))
282         {
283         case 'blacklistadminpanelaction':
284             $base = strtolower(mb_substr($cls, 0, -6));
285             include_once INSTALLDIR.'/plugins/Blacklist/'.$base.'.php';
286             return false;
287         default:
288             return true;
289         }
290     }
291
292     /**
293      * Plugin version data
294      *
295      * @param array &$versions array of version blocks
296      *
297      * @return boolean hook value
298      */
299
300     function onPluginVersion(&$versions)
301     {
302         $versions[] = array('name' => 'Blacklist',
303                             'version' => self::VERSION,
304                             'author' => 'Evan Prodromou',
305                             'homepage' =>
306                             'http://status.net/wiki/Plugin:Blacklist',
307                             'description' =>
308                             _m('Keep a blacklist of forbidden nickname '.
309                                'and URL patterns.'));
310         return true;
311     }
312
313     /**
314      * Determines if our admin panel can be shown
315      *
316      * @param string  $name  name of the admin panel
317      * @param boolean &$isOK result
318      *
319      * @return boolean hook value
320      */
321
322     function onAdminPanelCheck($name, &$isOK)
323     {
324         if ($name == 'blacklist') {
325             $isOK = $this->canAdmin;
326             return false;
327         }
328
329         return true;
330     }
331
332     /**
333      * Add our tab to the admin panel
334      *
335      * @param Widget $nav Admin panel nav
336      *
337      * @return boolean hook value
338      */
339
340     function onEndAdminPanelNav($nav)
341     {
342         if (AdminPanelAction::canAdmin('blacklist')) {
343
344             $action_name = $nav->action->trimmed('action');
345
346             $nav->out->menuItem(common_local_url('blacklistadminpanel'),
347                                 _('Blacklist'),
348                                 _('Blacklist configuration'),
349                                 $action_name == 'blacklistadminpanel',
350                                 'nav_blacklist_admin_panel');
351         }
352
353         return true;
354     }
355 }