diff --git a/app/controllers/my_profile/cms_controller.rb b/app/controllers/my_profile/cms_controller.rb index 0b27c0c..352fc37 100644 --- a/app/controllers/my_profile/cms_controller.rb +++ b/app/controllers/my_profile/cms_controller.rb @@ -1,8 +1,27 @@ class CmsController < MyProfileController - protect 'post_content', :profile, :except => [:set_home_page] protect 'edit_profile', :profile, :only => [:set_home_page] + def self.protect_if(*args) + before_filter(*args) do |c| + user, profile = c.send(:user), c.send(:profile) + if yield(c, user, profile) + true + else + render_access_denied(c) + false + end + end + end + + protect_if :except => [:set_home_page, :edit, :destroy, :publish] do |c, user, profile| + user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile)) + end + + protect_if :only => [:edit, :destroy, :publish] do |c, user, profile| + profile.articles.find(c.params[:id]).allow_post_content?(user) + end + alias :check_ssl_orig :check_ssl # Redefines the SSL checking to avoid requiring SSL when creating the "New # publication" button on article's public view. diff --git a/app/models/article.rb b/app/models/article.rb index 9686564..cbc92e9 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -214,11 +214,8 @@ class Article < ActiveRecord::Base end end - def allow_post_content?(logged_person = nil) - if logged_person && logged_person.has_permission?('post_content', profile) - return true - end - false + def allow_post_content?(user = nil) + user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile) && (user == self.creator)) end def comments_updated @@ -291,6 +288,11 @@ class Article < ActiveRecord::Base self.find(:all, :include => :taggings, :conditions => ['taggings.tag_id = ?', tag.id]) end + def creator + creator_id = versions[0][:last_changed_by_id] + creator_id && Profile.find(creator_id) + end + private def sanitize_tag_list diff --git a/app/models/profile.rb b/app/models/profile.rb index ecfdd9f..d86bd6e 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -33,7 +33,7 @@ class Profile < ActiveRecord::Base 'edit_profile' => N_('Edit profile'), 'destroy_profile' => N_('Destroy profile'), 'manage_memberships' => N_('Manage memberships'), - 'post_content' => N_('Post content'), + 'post_content' => N_('Manage content'), # changed only presentation name to keep already given permissions 'edit_profile_design' => N_('Edit profile design'), 'manage_products' => N_('Manage products'), 'manage_friends' => N_('Manage friends'), @@ -42,6 +42,7 @@ class Profile < ActiveRecord::Base 'moderate_comments' => N_('Moderate comments'), 'edit_appearance' => N_('Edit appearance'), 'view_private_content' => N_('View private content'), + 'publish_content' => N_('Publish content'), } acts_as_accessible diff --git a/test/functional/cms_controller_test.rb b/test/functional/cms_controller_test.rb index 42f6a63..69665c0 100644 --- a/test/functional/cms_controller_test.rb +++ b/test/functional/cms_controller_test.rb @@ -1148,4 +1148,58 @@ class CmsControllerTest < Test::Unit::TestCase assert_not_includes assigns(:article_types).map{|at|at[:name]}, 'Event' end + should 'not allow user without permission create an article in community' do + c = Community.create!(:name => 'test_comm', :identifier => 'test_comm') + u = create_user_with_permission('test_user', 'bogus_permission', c) + login_as :test_user + + get :new, :profile => c.identifier + assert_response :forbidden + assert_template 'access_denied.rhtml' + end + + should 'allow user with permission create an article in community' do + c = Community.create!(:name => 'test_comm', :identifier => 'test_comm') + u = create_user_with_permission('test_user', 'publish_content', c) + login_as :test_user + + get :new, :profile => c.identifier, :type => 'TinyMceArticle' + assert_response :success + assert_template 'edit' + end + + should 'not allow user edit article if he has publish permission but is not owner' do + c = Community.create!(:name => 'test_comm', :identifier => 'test_comm') + u = create_user_with_permission('test_user', 'publish_content', c) + a = c.articles.create!(:name => 'test_article') + login_as :test_user + + get :edit, :profile => c.identifier, :id => a.id + assert_response :forbidden + assert_template 'access_denied.rhtml' + end + + should 'not allow user edit article if he is owner but has no publish permission' do + c = Community.create!(:name => 'test_comm', :identifier => 'test_comm') + u = create_user_with_permission('test_user', 'bogus_permission', c) + a = c.articles.create!(:name => 'test_article', :last_changed_by => u) + login_as :test_user + + get :edit, :profile => c.identifier, :id => a.id + assert_response :forbidden + assert_template 'access_denied.rhtml' + end + + should 'allow user edit article if he is owner and has publish permission' do + c = Community.create!(:name => 'test_comm', :identifier => 'test_comm') + u = create_user_with_permission('test_user', 'publish_content', c) + a = c.articles.create!(:name => 'test_article', :last_changed_by => u) + login_as :test_user + + get :edit, :profile => c.identifier, :id => a.id + + assert_response :success + assert_template 'edit' + end + end diff --git a/test/unit/article_test.rb b/test/unit/article_test.rb index d3a0344..33b44f3 100644 --- a/test/unit/article_test.rb +++ b/test/unit/article_test.rb @@ -763,4 +763,20 @@ class ArticleTest < Test::Unit::TestCase assert_match(/-owner/, a.cache_key({}, c)) end + should 'have a creator method' do + c = Community.create!(:name => 'new_comm') + a = c.articles.create!(:name => 'a test article', :last_changed_by => profile) + p = create_user('other_user').person + a.update_attributes(:body => 'some content', :last_changed_by => p); a.save! + assert_equal profile, a.creator + end + + should 'allow creator to edit if is publisher' do + c = Community.create!(:name => 'new_comm') + p = create_user_with_permission('test_user', 'publish_content', c) + a = c.articles.create!(:name => 'a test article', :last_changed_by => p) + + assert a.allow_post_content?(p) + end + end -- libgit2 0.21.2