]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/Blacklist/BlacklistPlugin.php
BlacklistPlugin accepts config values for patterns
[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
51     private $_nicknamePatterns = array();
52     private $_urlPatterns  = array();
53
54     function initialize()
55     {
56         $this->_nicknamePatterns = array_merge($this->nicknames,
57                                                $this->_configArray('blacklist', 'nicknames'));
58
59         $this->_urlPatterns = array_merge($this->urls,
60                                           $this->_configArray('blacklist', 'urls'));
61     }
62
63     function _configArray($section, $setting)
64     {
65         $config = common_config($section, $setting);
66
67         if (empty($config)) {
68             return array();
69         } else if (is_array($config)) {
70             return $config;
71         } else if (is_string($config)) {
72             return explode("\t", $config);
73         } else {
74             throw new Exception("Unknown data type for config $section + $setting");
75         }
76     }
77
78     /**
79      * Hook registration to prevent blacklisted homepages or nicknames
80      *
81      * Throws an exception if there's a blacklisted homepage or nickname.
82      *
83      * @param Action $action Action being called (usually register)
84      *
85      * @return boolean hook value
86      */
87
88     function onStartRegistrationTry($action)
89     {
90         $homepage = strtolower($action->trimmed('homepage'));
91
92         if (!empty($homepage)) {
93             if (!$this->_checkUrl($homepage)) {
94                 $msg = sprintf(_m("You may not register with homepage '%s'"),
95                                $homepage);
96                 throw new ClientException($msg);
97             }
98         }
99
100         $nickname = strtolower($action->trimmed('nickname'));
101
102         if (!empty($nickname)) {
103             if (!$this->_checkNickname($nickname)) {
104                 $msg = sprintf(_m("You may not register with nickname '%s'"),
105                                $nickname);
106                 throw new ClientException($msg);
107             }
108         }
109
110         return true;
111     }
112
113     /**
114      * Hook profile update to prevent blacklisted homepages or nicknames
115      *
116      * Throws an exception if there's a blacklisted homepage or nickname.
117      *
118      * @param Action $action Action being called (usually register)
119      *
120      * @return boolean hook value
121      */
122
123     function onStartProfileSaveForm($action)
124     {
125         $homepage = strtolower($action->trimmed('homepage'));
126
127         if (!empty($homepage)) {
128             if (!$this->_checkUrl($homepage)) {
129                 $msg = sprintf(_m("You may not use homepage '%s'"),
130                                $homepage);
131                 throw new ClientException($msg);
132             }
133         }
134
135         $nickname = strtolower($action->trimmed('nickname'));
136
137         if (!empty($nickname)) {
138             if (!$this->_checkNickname($nickname)) {
139                 $msg = sprintf(_m("You may not use nickname '%s'"),
140                                $nickname);
141                 throw new ClientException($msg);
142             }
143         }
144
145         return true;
146     }
147
148     /**
149      * Hook notice save to prevent blacklisted urls
150      *
151      * Throws an exception if there's a blacklisted url in the content.
152      *
153      * @param Notice &$notice Notice being saved
154      *
155      * @return boolean hook value
156      */
157
158     function onStartNoticeSave(&$notice)
159     {
160         common_replace_urls_callback($notice->content,
161                                      array($this, 'checkNoticeUrl'));
162         return true;
163     }
164
165     /**
166      * Helper callback for notice save
167      *
168      * Throws an exception if there's a blacklisted url in the content.
169      *
170      * @param string $url URL in the notice content
171      *
172      * @return boolean hook value
173      */
174
175     function checkNoticeUrl($url)
176     {
177         // It comes in special'd, so we unspecial it
178         // before comparing against patterns
179
180         $url = htmlspecialchars_decode($url);
181
182         if (!$this->_checkUrl($url)) {
183             $msg = sprintf(_m("You may not use url '%s' in notices"),
184                            $url);
185             throw new ClientException($msg);
186         }
187
188         return $url;
189     }
190
191     /**
192      * Helper for checking URLs
193      *
194      * Checks an URL against our patterns for a match.
195      *
196      * @param string $url URL to check
197      *
198      * @return boolean true means it's OK, false means it's bad
199      */
200
201     private function _checkUrl($url)
202     {
203         foreach ($this->_urlPatterns as $pattern) {
204             if (preg_match("/$pattern/", $url)) {
205                 return false;
206             }
207         }
208
209         return true;
210     }
211
212     /**
213      * Helper for checking nicknames
214      *
215      * Checks a nickname against our patterns for a match.
216      *
217      * @param string $nickname nickname to check
218      *
219      * @return boolean true means it's OK, false means it's bad
220      */
221
222     private function _checkNickname($nickname)
223     {
224         foreach ($this->_nicknamePatterns as $pattern) {
225             if (preg_match("/$pattern/", $nickname)) {
226                 return false;
227             }
228         }
229
230         return true;
231     }
232
233     function onPluginVersion(&$versions)
234     {
235         $versions[] = array('name' => 'Blacklist',
236                             'version' => self::VERSION,
237                             'author' => 'Evan Prodromou',
238                             'homepage' => 'http://status.net/wiki/Plugin:Blacklist',
239                             'description' =>
240                             _m('Keep a blacklist of forbidden nickname and URL patterns.'));
241         return true;
242     }
243 }