From ff9c6ec057f3ff04b82afec4825d181af691cda0 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Tue, 7 Jul 2009 23:49:43 +0000 Subject: [PATCH 02/11] BUGFIX: Improvement permission checking of postblog and BlogEntryForm --- code/BlogHolder.php | 20 +++++++++--- tests/BlogHolderFunctionalTest.php | 49 ++++++++++++++++++++++++++++++ tests/BlogHolderFunctionalTest.yml | 20 ++++++++++++ 3 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 tests/BlogHolderFunctionalTest.php create mode 100644 tests/BlogHolderFunctionalTest.yml diff --git a/code/BlogHolder.php b/code/BlogHolder.php index 2bdc475..ec71169 100644 --- a/code/BlogHolder.php +++ b/code/BlogHolder.php @@ -166,6 +166,16 @@ class BlogHolder extends Page { } class BlogHolder_Controller extends Page_Controller { + + static $allowed_actions = array( + 'postblog' => 'BLOGMANAGEMENT', + 'post' => 'BLOGMANAGEMENT', + 'BlogEntryForm' => 'BLOGMANAGEMENT', + 'rss', + 'tag', + 'showarchive', + ); + function init() { parent::init(); @@ -258,9 +268,7 @@ class BlogHolder_Controller extends Page_Controller { * Post a new blog entry */ function post(){ - if(!Permission::check('ADMIN')){ - Security::permissionFailure($this, _t('BlogHolder.HAVENTPERM', 'Posting blogs is an administrator task. Please log in.')); - } + if(!Permission::check('BLOGMANAGEMENT')) return Security::permissionFailure(); $page = $this->customise(array( 'Content' => false, @@ -283,6 +291,8 @@ class BlogHolder_Controller extends Page_Controller { * A simple form for creating blog entries */ function BlogEntryForm() { + if(!Permission::check('BLOGMANAGEMENT')) return Security::permissionFailure(); + Requirements::javascript('jsparty/behaviour.js'); Requirements::javascript('jsparty/prototype.js'); Requirements::javascript('jsparty/scriptaculous/effects.js'); @@ -342,10 +352,12 @@ class BlogHolder_Controller extends Page_Controller { } function postblog($data, $form) { + if(!Permission::check('BLOGMANAGEMENT')) return Security::permissionFailure(); + Cookie::set("BlogHolder_Name", $data['Author']); $blogentry = false; - if($data['ID']) { + if(isset($data['ID']) && $data['ID']) { $blogentry = DataObject::get_by_id("BlogEntry", $data['ID']); } diff --git a/tests/BlogHolderFunctionalTest.php b/tests/BlogHolderFunctionalTest.php new file mode 100644 index 0000000..566cf00 --- /dev/null +++ b/tests/BlogHolderFunctionalTest.php @@ -0,0 +1,49 @@ +objFromFixture('BlogHolder', 'blogholder'); + $blogHolder->publish('Stage', 'LIve'); + $blogEntry = $this->objFromFixture('BlogEntry', 'entry1'); + $blogEntry->publish('Stage', 'LIve'); + } + + function testFrontendBlogPostRequiresPermission() { + // get valid SecurityID (from comments form, would usually be copy/pasted) + $blogEntry = $this->objFromFixture('BlogEntry', 'entry1'); + $response = $this->get($blogEntry->URLSegment); + $securityID = Session::get('SecurityID'); + + // without login + $data = array( + 'Title'=>'Disallowed', + 'Author'=>'Disallowed', + 'Content'=>'Disallowed', + 'action_postblog' => 'Post blog entry', + 'SecurityID' => $securityID + ); + $response = $this->post('blog/BlogEntryForm', $data); + $this->assertFalse(DataObject::get_one('BlogEntry', sprintf("Title = 'Disallowed'"))); + + // with login + $blogEditor = $this->objFromFixture('Member', 'blog_editor'); + $blogEditor->logIn(); + $data = array( + 'Title'=>'Allowed', + 'Author'=>'Allowed', + 'Content'=>'Allowed', + 'action_postblog' => 'Post blog entry', + 'SecurityID' => $securityID + ); + $response = $this->post('blog/BlogEntryForm', $data); + $this->assertType('BlogEntry', DataObject::get_one('BlogEntry', sprintf("Title = 'Allowed'"))); + } +} \ No newline at end of file diff --git a/tests/BlogHolderFunctionalTest.yml b/tests/BlogHolderFunctionalTest.yml new file mode 100644 index 0000000..561c1ba --- /dev/null +++ b/tests/BlogHolderFunctionalTest.yml @@ -0,0 +1,20 @@ +Permission: + blog_management: + Code: BLOGMANAGEMENT +Group: + blog_editors: + Code: blog-editors + Permissions: =>Permission.blog_management +Member: + blog_editor: + Email: blogeditor@test.com + Groups: =>Group.blog_editors +BlogHolder: + blogholder: + Title: Blog Holder + URLSegment: blog +BlogEntry: + entry1: + Title: Blog Entry + ProvideComments: 1 + Parent: =>BlogHolder.blogholder \ No newline at end of file From 26ad18d3854eeac45d0768197b544169f4b7339c Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Wed, 8 Jul 2009 01:25:13 +0000 Subject: [PATCH 03/11] MINOR Merged from trunk --- tests/BlogHolderFunctionalTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/BlogHolderFunctionalTest.php b/tests/BlogHolderFunctionalTest.php index 566cf00..4137d27 100644 --- a/tests/BlogHolderFunctionalTest.php +++ b/tests/BlogHolderFunctionalTest.php @@ -11,9 +11,9 @@ class BlogHolderFunctionalTest extends FunctionalTest { parent::setUp(); $blogHolder = $this->objFromFixture('BlogHolder', 'blogholder'); - $blogHolder->publish('Stage', 'LIve'); + $blogHolder->publish('Stage', 'Live'); $blogEntry = $this->objFromFixture('BlogEntry', 'entry1'); - $blogEntry->publish('Stage', 'LIve'); + $blogEntry->publish('Stage', 'Live'); } function testFrontendBlogPostRequiresPermission() { From bcaea3eafb7ac0421715409a2473e12b4f49dd57 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Tue, 22 Dec 2009 21:07:44 +0000 Subject: [PATCH 06/11] BUGFIX Limiting BlogHolder->LandingPageFreshness to requests without a controller action only. Controller actions are not regarded as the "landing page", as they cause other views like 'tags' or 'rss', which shouldn't be filtered (from r96200) --- code/BlogTree.php | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/code/BlogTree.php b/code/BlogTree.php index 94e85de..7f55cc5 100644 --- a/code/BlogTree.php +++ b/code/BlogTree.php @@ -147,9 +147,10 @@ class BlogTree extends Page { * @param string tag Only get blog entries with this tag * @param string date Only get blog entries on this date - either a year, or a year-month eg '2008' or '2008-02' * @param callback retrieveCallback A function to call with pagetype, filter and limit for custom blog sorting or filtering + * @param string $where * @return DataObjectSet */ - public function Entries($limit = '', $tag = '', $date = '', $retrieveCallback = null) { + public function Entries($limit = '', $tag = '', $date = '', $retrieveCallback = null, $filter = '') { $tagCheck = ''; $dateCheck = ''; @@ -161,7 +162,7 @@ class BlogTree extends Page { $tagCheck = "AND `BlogEntry`.Tags LIKE '%$SQL_tag%'"; } } - + if ($date) { if(strpos($date, '-')) { $year = (int) substr($date, 0, strpos($date, '-')); @@ -185,14 +186,7 @@ class BlogTree extends Page { } } } - elseif ($this->LandingPageFreshness) { - if(defined('DB::USE_ANSI_SQL')) { - $dateCheck = "AND \"BlogEntry\".\"Date\" > NOW() - INTERVAL " . $this->LandingPageFreshness; - } else { - $dateCheck = "AND `BlogEntry`.Date > NOW() - INTERVAL " . $this->LandingPageFreshness; - } - } - + // Build a list of all IDs for BlogHolders that are children of us $holderIDs = $this->BlogHolderIDs(); @@ -200,10 +194,11 @@ class BlogTree extends Page { if (empty($holderIDs)) return false; // Otherwise, do the actual query + if($filter) $filter .= ' AND '; if(defined('DB::USE_ANSI_SQL')) { - $where = '"ParentID" IN (' . implode(',', $holderIDs) . ") $tagCheck $dateCheck"; + $filter .= '"ParentID" IN (' . implode(',', $holderIDs) . ") $tagCheck $dateCheck"; } else { - $where = 'ParentID IN (' . implode(',', $holderIDs) . ") $tagCheck $dateCheck"; + $filter .= '`ParentID` IN (' . implode(',', $holderIDs) . ") $tagCheck $dateCheck"; } if(defined('DB::USE_ANSI_SQL')) { @@ -213,8 +208,8 @@ class BlogTree extends Page { } // By specifying a callback, you can alter the SQL, or sort on something other than date. - if ($retrieveCallback) return call_user_func($retrieveCallback, 'BlogEntry', $where, $limit, $order); - else return DataObject::get('BlogEntry', $where, $order, '', $limit); + if ($retrieveCallback) return call_user_func($retrieveCallback, 'BlogEntry', $filter, $limit, $order); + else return DataObject::get('BlogEntry', $filter, $order, '', $limit); } } @@ -255,9 +250,20 @@ class BlogTree_Controller extends Page_Controller { function BlogEntries($limit = null) { if ($limit === null) $limit = BlogTree::$default_entries_limit; - + + // only use freshness if no action is present (might be displaying tags or rss) + if ($this->LandingPageFreshness && !$this->request->param('Action')) { + if(defined('DB::USE_ANSI_SQL')) { + $filter = "\"BlogEntry\".\"Date\" > NOW() - INTERVAL " . $this->LandingPageFreshness; + } else { + $filter = "`BlogEntry`.Date > NOW() - INTERVAL " . $this->LandingPageFreshness; + } + } else { + $filter = ''; + } + $start = isset($_GET['start']) ? (int) $_GET['start'] : 0; - return $this->Entries("$start,$limit", BlogURL::tag(), BlogURL::date()); + return $this->Entries("$start,$limit", BlogURL::tag(), BlogURL::date(), null, $filter); } function IncludeBlogRSS() { @@ -323,3 +329,4 @@ class BlogTree_Controller extends Page_Controller { return parent::defaultAction($action); } } +?> \ No newline at end of file From c1f20717d1ba465faad68601b04df7acc492ba95 Mon Sep 17 00:00:00 2001 From: Saophalkun Ponlu Date: Thu, 11 Mar 2010 01:28:37 +0000 Subject: [PATCH 08/11] BUGFIX: returns null when there's no blog IDs --- code/ArchiveWidget.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/ArchiveWidget.php b/code/ArchiveWidget.php index 0746d11..d614db0 100644 --- a/code/ArchiveWidget.php +++ b/code/ArchiveWidget.php @@ -48,6 +48,8 @@ class ArchiveWidget extends Widget { $container = BlogTree::current(); $ids = $container->BlogHolderIDs(); + if(empty($ids)) return $results; + $stage = Versioned::current_stage(); $suffix = (!$stage || $stage == 'Stage') ? "" : "_$stage"; From 91bc0bc772231963b4495fed3dd050bdf1b00a23 Mon Sep 17 00:00:00 2001 From: Carlos Barberis Date: Fri, 19 Mar 2010 00:40:23 +0000 Subject: [PATCH 09/11] Changed module maintainer contact details --- README | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README b/README index 4e582d7..d0f98b3 100644 --- a/README +++ b/README @@ -3,8 +3,11 @@ Blog Module #################################################### # Maintainer Contact -Andrew O'Neil (Nickname: aoneil) - +Carlos Barberis (Nickname: carlos) + + +Phalkunz (Nickname: carlos) + # Requirements SilverStripe minimum version 2.3.0 From 965b81c0a31ce3f2691f41627bf0fdfeb99fde7e Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Fri, 20 Aug 2010 02:37:35 +0000 Subject: [PATCH 10/11] FEATURE: allow disabling of the built in RSS link generated to allow feedburner links etc to be used otherwise. MINOR: removed commented out code --- code/BlogTree.php | 45 ++++++++++----------------------------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/code/BlogTree.php b/code/BlogTree.php index 7f55cc5..571190d 100644 --- a/code/BlogTree.php +++ b/code/BlogTree.php @@ -13,6 +13,13 @@ class BlogTree extends Page { // Default number of blog entries to show static $default_entries_limit = 10; + /** + * @var bool Include an automatic link to the rss feed for + * the browser. Disabling this will allow you to include your + * own feedburner link + */ + static $include_rss_link = true; + static $db = array( 'Name' => 'Varchar', 'InheritSideBar' => 'Boolean', @@ -243,7 +250,9 @@ class BlogTree_Controller extends Page_Controller { function init() { parent::init(); - $this->IncludeBlogRSS(); + if(BlogTree::$include_rss_link) { + $this->IncludeBlogRSS(); + } Requirements::themedCSS("blog"); } @@ -271,40 +280,6 @@ class BlogTree_Controller extends Page_Controller { RSSFeed::linkToFeed($this->Link() . "rss", _t('BlogHolder.RSSFEED',"RSS feed of these blogs")); } - /* - * @todo: It doesn't look like these are used. Remove if no-one complains - Hamish - - /** - * Gets the archived blogs for a particular month or year, in the format /year/month/ eg: /2008/10/ - * / - function showarchive() { - $month = addslashes($this->urlParams['ID']); - return array( - "Children" => DataObject::get('SiteTree', "ParentID = $this->ID AND DATE_FORMAT(`BlogEntry`.`Date`, '%Y-%M') = '$month'"), - ); - } - - function ArchiveMonths() { - $months = DB::query("SELECT DISTINCT DATE_FORMAT(`BlogEntry`.`Date`, '%M') AS `Month`, DATE_FORMAT(`BlogEntry`.`Date`, '%Y') AS `Year` FROM `BlogEntry` ORDER BY `BlogEntry`.`Date` DESC"); - $output = new DataObjectSet(); - foreach($months as $month) { - $month['Link'] = $this->Link() . "showarchive/$month[Year]-$month[Month]"; - $output->push(new ArrayData($month)); - } - - return $output; - } - - function tag() { - if (Director::urlParam('Action') == 'tag') { - return array( - 'Tag' => Convert::raw2xml(Director::urlParam('ID')) - ); - } - return array(); - } - */ - /** * Get the rss feed for this blog holder's entries */ From a6734d3609cc9b785167560c71ff35695dc1b4ba Mon Sep 17 00:00:00 2001 From: Saophalkun Ponlu Date: Sun, 3 Oct 2010 21:40:01 +0000 Subject: [PATCH 11/11] BUGFIX Fixed XSS vulnerability in BlogTree? when filtering by tags --- code/BlogTree.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/BlogTree.php b/code/BlogTree.php index 571190d..ab42af3 100644 --- a/code/BlogTree.php +++ b/code/BlogTree.php @@ -222,7 +222,7 @@ class BlogTree extends Page { class BlogURL { static function tag() { - if (Director::urlParam('Action') == 'tag') return Director::urlParam('ID'); + if (Director::urlParam('Action') == 'tag') return Convert::raw2xml(Director::urlParam('ID')); return ''; }