From 986a32223177a759b0ef071822d227011ee1b3c7 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 7 Mar 2009 09:43:50 -0800 Subject: Limit duplicate notices in a particular time period (default 60s) We disallow posting a notice with duplicate content more than once a minute. Conflicts: config.php.sample --- classes/Notice.php | 47 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) (limited to 'classes') diff --git a/classes/Notice.php b/classes/Notice.php index 907239b08..eac90ce95 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -121,6 +121,8 @@ class Notice extends Memcached_DataObject $profile = Profile::staticGet($profile_id); + $final = common_shorten_links($content); + if (!$profile) { common_log(LOG_ERR, 'Problem saving notice. Unknown user.'); return _('Problem saving notice. Unknown user.'); @@ -131,7 +133,12 @@ class Notice extends Memcached_DataObject return _('Too many notices too fast; take a breather and post again in a few minutes.'); } - $banned = common_config('profile', 'banned'); + if (common_config('site', 'dupelimit') > 0 && !Notice::checkDupes($profile_id, $final)) { + common_log(LOG_WARNING, 'Dupe posting by profile #' . $profile_id . '; throttled.'); + return _('Too many duplicate messages too quickly; take a breather and post again in a few minutes.'); + } + + $banned = common_config('profile', 'banned'); if ( in_array($profile_id, $banned) || in_array($profile->nickname, $banned)) { common_log(LOG_WARNING, "Attempted post from banned user: $profile->nickname (user id = $profile_id)."); @@ -155,12 +162,12 @@ class Notice extends Memcached_DataObject $notice->query('BEGIN'); - $notice->reply_to = $reply_to; - $notice->created = common_sql_now(); - $notice->content = common_shorten_links($content); - $notice->rendered = common_render_content($notice->content, $notice); - $notice->source = $source; - $notice->uri = $uri; + $notice->reply_to = $reply_to; + $notice->created = common_sql_now(); + $notice->content = $final; + $notice->rendered = common_render_content($final, $notice); + $notice->source = $source; + $notice->uri = $uri; if (Event::handle('StartNoticeSave', array(&$notice))) { @@ -204,6 +211,32 @@ class Notice extends Memcached_DataObject return $notice; } + static function checkDupes($profile_id, $content) { + $profile = Profile::staticGet($profile_id); + if (!$profile) { + return false; + } + $notice = $profile->getNotices(0, NOTICE_CACHE_WINDOW); + if ($notice) { + $last = 0; + while ($notice->fetch()) { + if (time() - strtotime($notice->created) >= common_config('site', 'dupelimit')) { + return true; + } else if ($notice->content == $content) { + return false; + } + } + } + # If we get here, oldest item in cache window is not + # old enough for dupe limit; do direct check against DB + $notice = new Notice(); + $notice->profile_id = $profile_id; + $notice->content = $content; + $notice->whereAdd('now() - created < ' . common_config('notice', 'dupelimit')); + $cnt = $notice->count(); + return ($cnt > 0); + } + static function checkEditThrottle($profile_id) { $profile = Profile::staticGet($profile_id); if (!$profile) { -- cgit v1.2.3-54-g00ecf From 0570c16e6ceb42d6b3afa93c1054e024091a3e08 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 7 Mar 2009 11:56:01 -0800 Subject: Add local directory for plugins, themes, etc. Added a local directory for locally-installed software. This is where you should put any code you write, themes, plugins, etc. so they don't get stomped by upgrades. --- classes/User.php | 3 ++- local/.gitignore | 0 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 local/.gitignore (limited to 'classes') diff --git a/classes/User.php b/classes/User.php index 8b0b9acd5..d9f30bec5 100644 --- a/classes/User.php +++ b/classes/User.php @@ -121,7 +121,8 @@ class User extends Memcached_DataObject static $blacklist = array('rss', 'xrds', 'doc', 'main', 'settings', 'notice', 'user', 'search', 'avatar', 'tag', 'tags', - 'api', 'message', 'group', 'groups'); + 'api', 'message', 'group', 'groups', + 'local'); $merged = array_merge($blacklist, common_config('nickname', 'blacklist')); return !in_array($nickname, $merged); } diff --git a/local/.gitignore b/local/.gitignore new file mode 100644 index 000000000..e69de29bb -- cgit v1.2.3-54-g00ecf From 1179ecd13d68e76d74ad94e2d3ca22d9681eeffe Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 7 Mar 2009 12:55:09 -0800 Subject: Fix nonce usage in OAuth store The OAuth store was failing on getting a request token, because the token value was forced to be non-null in the DB. Let this value be null, and use the correct primary key (consumer, timestamp, nonce). Drop the reference to token table, and don't ever use it. --- classes/Nonce.php | 9 ++++----- classes/laconica.ini | 4 ++-- db/laconica.sql | 5 ++--- lib/oauthstore.php | 3 +-- 4 files changed, 9 insertions(+), 12 deletions(-) (limited to 'classes') diff --git a/classes/Nonce.php b/classes/Nonce.php index 2c0edfa14..486a65a3c 100644 --- a/classes/Nonce.php +++ b/classes/Nonce.php @@ -4,22 +4,21 @@ */ require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; -class Nonce extends Memcached_DataObject +class Nonce extends Memcached_DataObject { ###START_AUTOCODE /* the code below is auto generated do not remove the above tag */ public $__table = 'nonce'; // table name public $consumer_key; // varchar(255) primary_key not_null - public $tok; // char(32) primary_key not_null + public $tok; // char(32) public $nonce; // char(32) primary_key not_null - public $ts; // datetime() not_null + public $ts; // datetime() primary_key not_null public $created; // datetime() not_null public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP /* Static get */ - function staticGet($k,$v=null) - { return Memcached_DataObject::staticGet('Nonce',$k,$v); } + function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Nonce',$k,$v); } /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE diff --git a/classes/laconica.ini b/classes/laconica.ini index 5fd2cd1f8..529454d99 100755 --- a/classes/laconica.ini +++ b/classes/laconica.ini @@ -145,7 +145,7 @@ id = N [nonce] consumer_key = 130 -tok = 130 +tok = 2 nonce = 130 ts = 142 created = 142 @@ -153,8 +153,8 @@ modified = 384 [nonce__keys] consumer_key = K -tok = K nonce = K +ts = K [notice] id = 129 diff --git a/db/laconica.sql b/db/laconica.sql index c2cd887de..098fa4fd1 100644 --- a/db/laconica.sql +++ b/db/laconica.sql @@ -181,15 +181,14 @@ create table token ( create table nonce ( consumer_key varchar(255) not null comment 'unique identifier, root URL', - tok char(32) not null comment 'identifying value', + tok char(32) null comment 'buggy old value, ignored', nonce char(32) not null comment 'nonce', ts datetime not null comment 'timestamp sent', created datetime not null comment 'date this record was created', modified timestamp comment 'date this record was modified', - constraint primary key (consumer_key, tok, nonce), - constraint foreign key (consumer_key, tok) references token (consumer_key, tok) + constraint primary key (consumer_key, ts, nonce) ) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin; /* One-to-many relationship of user to openid_url */ diff --git a/lib/oauthstore.php b/lib/oauthstore.php index 9af05ea2d..7d2e1f27b 100644 --- a/lib/oauthstore.php +++ b/lib/oauthstore.php @@ -58,12 +58,11 @@ class LaconicaOAuthDataStore extends OAuthDataStore { $n = new Nonce(); $n->consumer_key = $consumer->key; - $n->tok = $token->key; + $n->ts = $timestamp; $n->nonce = $nonce; if ($n->find(true)) { return true; } else { - $n->ts = $timestamp; $n->created = DB_DataObject_Cast::dateTime(); $n->insert(); return false; -- cgit v1.2.3-54-g00ecf From bea3fca1899dddda8d1c52c16a761dd23c9ce8b8 Mon Sep 17 00:00:00 2001 From: Adrian Lang Date: Sat, 7 Mar 2009 23:04:30 +0100 Subject: Fix bug in dupe checking on notice post when there is no notice in cache. --- classes/Notice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'classes') diff --git a/classes/Notice.php b/classes/Notice.php index eac90ce95..ac4db944f 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -234,7 +234,7 @@ class Notice extends Memcached_DataObject $notice->content = $content; $notice->whereAdd('now() - created < ' . common_config('notice', 'dupelimit')); $cnt = $notice->count(); - return ($cnt > 0); + return ($cnt == 0); } static function checkEditThrottle($profile_id) { -- cgit v1.2.3-54-g00ecf From b9194e792369506cd2514dcad3e26ce483e6b72d Mon Sep 17 00:00:00 2001 From: CiaranG Date: Wed, 11 Mar 2009 09:12:39 +0000 Subject: Correction to recently added dupe-checking feature - was using wrong config value --- classes/Notice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'classes') diff --git a/classes/Notice.php b/classes/Notice.php index ac4db944f..1e3b330f2 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -232,7 +232,7 @@ class Notice extends Memcached_DataObject $notice = new Notice(); $notice->profile_id = $profile_id; $notice->content = $content; - $notice->whereAdd('now() - created < ' . common_config('notice', 'dupelimit')); + $notice->whereAdd('now() - created < ' . common_config('site', 'dupelimit')); $cnt = $notice->count(); return ($cnt == 0); } -- cgit v1.2.3-54-g00ecf From c08e4d904ec80144379c5728e2274e3513e6c819 Mon Sep 17 00:00:00 2001 From: CiaranG Date: Wed, 11 Mar 2009 23:41:30 +0000 Subject: PostgreSQL - a few more query compatibility issues (submitted by oxygene) --- actions/peopletag.php | 2 +- actions/sup.php | 4 +++- classes/Notice.php | 6 +++++- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'classes') diff --git a/actions/peopletag.php b/actions/peopletag.php index 6b1e34f1a..5add75485 100644 --- a/actions/peopletag.php +++ b/actions/peopletag.php @@ -119,7 +119,7 @@ class PeopletagAction extends Action 'FROM profile JOIN profile_tag ' . 'ON profile.id = profile_tag.tagger ' . 'WHERE profile_tag.tagger = profile_tag.tagged ' . - 'AND tag = "%s" ' . + "AND tag = '%s' " . 'ORDER BY profile_tag.modified DESC%s'; $profile->query(sprintf($qry, $this->tag, $lim)); diff --git a/actions/sup.php b/actions/sup.php index f4b1cda23..8ef9207fa 100644 --- a/actions/sup.php +++ b/actions/sup.php @@ -65,7 +65,9 @@ class SupAction extends Action $notice->query('SELECT profile_id, max(id) AS max_id ' . 'FROM notice ' . - 'WHERE created > (now() - ' . $seconds . ') ' . + ((common_config('db','type') == 'pgsql') ? + 'WHERE extract(epoch from created) > (extract(epoch from now()) - ' . $seconds . ') ' : + 'WHERE created > (now() - ' . $seconds . ') ' ) . 'GROUP BY profile_id'); $updates = array(); diff --git a/classes/Notice.php b/classes/Notice.php index 1e3b330f2..3087e39a7 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -232,7 +232,11 @@ class Notice extends Memcached_DataObject $notice = new Notice(); $notice->profile_id = $profile_id; $notice->content = $content; - $notice->whereAdd('now() - created < ' . common_config('site', 'dupelimit')); + if (common_config('db','type') == 'pgsql') + $notice->whereAdd('extract(epoch from now() - created) < ' . common_config('site', 'dupelimit')); + else + $notice->whereAdd('now() - created < ' . common_config('site', 'dupelimit')); + $cnt = $notice->count(); return ($cnt == 0); } -- cgit v1.2.3-54-g00ecf