* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
-
class BlacklistPlugin extends Plugin
{
const VERSION = STATUSNET_VERSION;
public $urls = array();
public $canAdmin = true;
- private $_nicknamePatterns = array();
- private $_urlPatterns = array();
-
- /**
- * Initialize the plugin
- *
- * @return void
- */
-
- function initialize()
+ function _getNicknamePatterns()
{
$confNicknames = $this->_configArray('blacklist', 'nicknames');
- $this->_nicknamePatterns = array_merge($this->nicknames,
- $confNicknames);
+ $dbNicknames = Nickname_blacklist::getPatterns();
+ return array_merge($this->nicknames,
+ $confNicknames,
+ $dbNicknames);
+ }
+
+ function _getUrlPatterns()
+ {
$confURLs = $this->_configArray('blacklist', 'urls');
- $this->_urlPatterns = array_merge($this->urls,
- $confURLs);
+ $dbURLs = Homepage_blacklist::getPatterns();
+
+ return array_merge($this->urls,
+ $confURLs,
+ $dbURLs);
+ }
+
+ /**
+ * Database schema setup
+ *
+ * @return boolean hook value
+ */
+ function onCheckSchema()
+ {
+ $schema = Schema::get();
+
+ // For storing blacklist patterns for nicknames
+ $schema->ensureTable('nickname_blacklist',
+ array(new ColumnDef('pattern',
+ 'varchar',
+ 255,
+ false,
+ 'PRI'),
+ new ColumnDef('created',
+ 'datetime',
+ null,
+ false)));
+
+ $schema->ensureTable('homepage_blacklist',
+ array(new ColumnDef('pattern',
+ 'varchar',
+ 255,
+ false,
+ 'PRI'),
+ new ColumnDef('created',
+ 'datetime',
+ null,
+ false)));
+
+ return true;
}
/**
*
* @return array configuration values
*/
-
function _configArray($section, $setting)
{
$config = common_config($section, $setting);
} else if (is_string($config)) {
return explode("\r\n", $config);
} else {
- throw new Exception("Unknown data type for config $section + $setting");
+ // TRANS: Exception thrown if the Blacklist plugin configuration is incorrect.
+ // TRANS: %1$s is a configuration section, %2$s is a configuration setting.
+ throw new Exception(sprintf(_m('Unknown data type for config %1$s + %2$s.'),$section, $setting));
}
}
*
* @return boolean hook value
*/
-
- function onStartRegistrationTry($action)
+ function onStartRegisterUser(&$user, &$profile)
{
- $homepage = strtolower($action->trimmed('homepage'));
+ $homepage = strtolower($profile->homepage);
if (!empty($homepage)) {
if (!$this->_checkUrl($homepage)) {
- $msg = sprintf(_m("You may not register with homepage '%s'"),
+ // TRANS: Validation failure for URL. %s is the URL.
+ $msg = sprintf(_m("You may not register with homepage \"%s\"."),
$homepage);
throw new ClientException($msg);
}
}
- $nickname = strtolower($action->trimmed('nickname'));
+ $nickname = strtolower($profile->nickname);
if (!empty($nickname)) {
if (!$this->_checkNickname($nickname)) {
- $msg = sprintf(_m("You may not register with nickname '%s'"),
+ // TRANS: Validation failure for nickname. %s is the nickname.
+ $msg = sprintf(_m("You may not register with nickname \"%s\"."),
$nickname);
throw new ClientException($msg);
}
*
* @return boolean hook value
*/
-
function onStartProfileSaveForm($action)
{
$homepage = strtolower($action->trimmed('homepage'));
if (!empty($homepage)) {
if (!$this->_checkUrl($homepage)) {
- $msg = sprintf(_m("You may not use homepage '%s'"),
+ // TRANS: Validation failure for URL. %s is the URL.
+ $msg = sprintf(_m("You may not use homepage \"%s\"."),
$homepage);
throw new ClientException($msg);
}
if (!empty($nickname)) {
if (!$this->_checkNickname($nickname)) {
- $msg = sprintf(_m("You may not use nickname '%s'"),
+ // TRANS: Validation failure for nickname. %s is the nickname.
+ $msg = sprintf(_m("You may not use nickname \"%s\"."),
$nickname);
throw new ClientException($msg);
}
*
* @return boolean hook value
*/
-
function onStartNoticeSave(&$notice)
{
common_replace_urls_callback($notice->content,
*
* @return boolean hook value
*/
-
function checkNoticeUrl($url)
{
// It comes in special'd, so we unspecial it
$url = htmlspecialchars_decode($url);
if (!$this->_checkUrl($url)) {
- $msg = sprintf(_m("You may not use url '%s' in notices"),
+ // TRANS: Validation failure for URL. %s is the URL.
+ $msg = sprintf(_m("You may not use URL \"%s\" in notices."),
$url);
throw new ClientException($msg);
}
*
* @return boolean true means it's OK, false means it's bad
*/
-
private function _checkUrl($url)
{
- foreach ($this->_urlPatterns as $pattern) {
- common_debug("Checking $url against $pattern");
- if (preg_match("/$pattern/", $url)) {
+ $patterns = $this->_getUrlPatterns();
+
+ foreach ($patterns as $pattern) {
+ if ($pattern != '' && preg_match("/$pattern/", $url)) {
return false;
}
}
*
* @return boolean true means it's OK, false means it's bad
*/
-
private function _checkNickname($nickname)
{
- foreach ($this->_nicknamePatterns as $pattern) {
- common_debug("Checking $nickname against $pattern");
- if (preg_match("/$pattern/", $nickname)) {
+ $patterns = $this->_getNicknamePatterns();
+
+ foreach ($patterns as $pattern) {
+ if ($pattern != '' && preg_match("/$pattern/", $nickname)) {
return false;
}
}
*
* @return boolean hook return
*/
-
function onRouterInitialized($m)
{
- $m->connect('admin/blacklist', array('action' => 'blacklistadminpanel'));
+ $m->connect('panel/blacklist', array('action' => 'blacklistadminpanel'));
return true;
}
*
* @return boolean hook return
*/
-
function onAutoload($cls)
{
switch (strtolower($cls))
{
+ case 'nickname_blacklist':
+ case 'homepage_blacklist':
+ include_once INSTALLDIR.'/plugins/Blacklist/'.ucfirst($cls).'.php';
+ return false;
case 'blacklistadminpanelaction':
$base = strtolower(mb_substr($cls, 0, -6));
include_once INSTALLDIR.'/plugins/Blacklist/'.$base.'.php';
*
* @return boolean hook value
*/
-
function onPluginVersion(&$versions)
{
$versions[] = array('name' => 'Blacklist',
'homepage' =>
'http://status.net/wiki/Plugin:Blacklist',
'description' =>
- _m('Keep a blacklist of forbidden nickname '.
+ // TRANS: Plugin description.
+ _m('Keeps a blacklist of forbidden nickname '.
'and URL patterns.'));
return true;
}
*
* @return boolean hook value
*/
-
function onAdminPanelCheck($name, &$isOK)
{
if ($name == 'blacklist') {
*
* @return boolean hook value
*/
-
function onEndAdminPanelNav($nav)
{
if (AdminPanelAction::canAdmin('blacklist')) {
$action_name = $nav->action->trimmed('action');
$nav->out->menuItem(common_local_url('blacklistadminpanel'),
- _('Blacklist'),
- _('Blacklist configuration'),
+ // TRANS: Menu item in admin panel.
+ _m('MENU','Blacklist'),
+ // TRANS: Tooltip for menu item in admin panel.
+ _m('TOOLTIP','Blacklist configuration.'),
$action_name == 'blacklistadminpanel',
'nav_blacklist_admin_panel');
}
$action->elementStart('li');
$this->checkboxAndText($action,
'blacklistnickname',
- _('Add this nickname pattern to blacklist'),
+ // TRANS: Checkbox label in the blacklist user form.
+ _m('Add this nickname pattern to blacklist'),
'blacklistnicknamepattern',
$this->patternizeNickname($user->nickname));
$action->elementEnd('li');
$action->elementStart('li');
$this->checkboxAndText($action,
'blacklisthomepage',
- _('Add this homepage pattern to blacklist'),
+ // TRANS: Checkbox label in the blacklist user form.
+ _m('Add this homepage pattern to blacklist'),
'blacklisthomepagepattern',
$this->patternizeHomepage($profile->homepage));
$action->elementEnd('li');
function onEndDeleteUser($action, $user)
{
- common_debug("Action args: " . print_r($action->args, true));
-
if ($action->boolean('blacklisthomepage')) {
$pattern = $action->trimmed('blacklisthomepagepattern');
- $confURLs = $this->_configArray('blacklist', 'urls');
- $confURLs[] = $pattern;
- Config::save('blacklist', 'urls', implode("\r\n", $confURLs));
+ Homepage_blacklist::ensurePattern($pattern);
}
if ($action->boolean('blacklistnickname')) {
$pattern = $action->trimmed('blacklistnicknamepattern');
- $confNicknames = $this->_configArray('blacklist', 'nicknames');
- $confNicknames[] = $pattern;
- Config::save('blacklist', 'nicknames', implode("\r\n", $confNicknames));
+ Nickname_blacklist::ensurePattern($pattern);
}
return true;
$hostname = parse_url($homepage, PHP_URL_HOST);
return $hostname;
}
+
+ function onStartHandleFeedEntry($activity)
+ {
+ return $this->_checkActivity($activity);
+ }
+
+ function onStartHandleSalmon($activity)
+ {
+ return $this->_checkActivity($activity);
+ }
+
+ function _checkActivity($activity)
+ {
+ $actor = $activity->actor;
+
+ if (empty($actor)) {
+ return true;
+ }
+
+ $homepage = strtolower($actor->link);
+
+ if (!empty($homepage)) {
+ if (!$this->_checkUrl($homepage)) {
+ // TRANS: Exception thrown trying to post a notice while having set a blocked homepage URL. %s is the blocked URL.
+ $msg = sprintf(_m("Users from \"%s\" are blocked."),
+ $homepage);
+ throw new ClientException($msg);
+ }
+ }
+
+ $nickname = strtolower($actor->poco->preferredUsername);
+
+ if (!empty($nickname)) {
+ if (!$this->_checkNickname($nickname)) {
+ // TRANS: Exception thrown trying to post a notice while having a blocked nickname. %s is the blocked nickname.
+ $msg = sprintf(_m("Notices from nickname \"%s\" disallowed."),
+ $nickname);
+ throw new ClientException($msg);
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Check URLs and homepages for blacklisted users.
+ */
+ function onStartSubscribe($subscriber, $other)
+ {
+ foreach (array($other->profileurl, $other->homepage) as $url) {
+
+ if (empty($url)) {
+ continue;
+ }
+
+ $url = strtolower($url);
+
+ if (!$this->_checkUrl($url)) {
+ // TRANS: Client exception thrown trying to subscribe to a person with a blocked homepage or site URL. %s is the blocked URL.
+ $msg = sprintf(_m("Users from \"%s\" are blocked."),
+ $url);
+ throw new ClientException($msg);
+ }
+ }
+
+ $nickname = $other->nickname;
+
+ if (!empty($nickname)) {
+ if (!$this->_checkNickname($nickname)) {
+ // TRANS: Client exception thrown trying to subscribe to a person with a blocked nickname. %s is the blocked nickname.
+ $msg = sprintf(_m("Cannot subscribe to nickname \"%s\"."),
+ $nickname);
+ throw new ClientException($msg);
+ }
+ }
+
+ return true;
+ }
}