From 766d3c974e30487eb858e72ede0710e6d4e3d855 Mon Sep 17 00:00:00 2001 From: Rodrigo Souto Date: Thu, 25 Oct 2012 00:10:42 +0000 Subject: [PATCH] [work-assignment] Defining download and upload restrictions --- app/controllers/my_profile/cms_controller.rb | 7 ++++++- plugins/work_assignment/lib/work_assignment_plugin.rb | 27 ++++++++++++++++++++++++++- plugins/work_assignment/lib/work_assignment_plugin/work_assignment.rb | 2 ++ plugins/work_assignment/test/functional/cms_controller_test.rb | 34 ++++++++++++++++++++++++++++++++++ plugins/work_assignment/test/functional/content_viewer_controller_test.rb | 41 +++++++++++++++++++++++++++++++++++++++++ plugins/work_assignment/test/unit/work_assingment_plugin_test.rb | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/functional/cms_controller_test.rb | 12 ++++++++++++ 7 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 plugins/work_assignment/test/functional/cms_controller_test.rb create mode 100644 plugins/work_assignment/test/functional/content_viewer_controller_test.rb create mode 100644 plugins/work_assignment/test/unit/work_assingment_plugin_test.rb diff --git a/app/controllers/my_profile/cms_controller.rb b/app/controllers/my_profile/cms_controller.rb index 6762255..8c6c858 100644 --- a/app/controllers/my_profile/cms_controller.rb +++ b/app/controllers/my_profile/cms_controller.rb @@ -16,7 +16,12 @@ class CmsController < MyProfileController before_filter :login_required, :except => [:suggest_an_article] - protect_if :except => [:suggest_an_article, :set_home_page, :edit, :destroy, :publish] do |c, user, profile| + protect_if :only => :upload_files do |c, user, profile| + article_id = c.params[:parent_id] + profile.articles.find(article_id).allow_create?(user) + end + + protect_if :except => [:suggest_an_article, :set_home_page, :edit, :destroy, :publish, :upload_files] do |c, user, profile| user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile)) end diff --git a/plugins/work_assignment/lib/work_assignment_plugin.rb b/plugins/work_assignment/lib/work_assignment_plugin.rb index 1d49ab4..ca733fe 100644 --- a/plugins/work_assignment/lib/work_assignment_plugin.rb +++ b/plugins/work_assignment/lib/work_assignment_plugin.rb @@ -5,7 +5,16 @@ class WorkAssignmentPlugin < Noosfero::Plugin end def self.plugin_description - _("New kind of content for work organization.") + _("New kind of content for organizations.") + end + + def self.can_download_submission?(user, submission) + work_assignment = submission.parent.parent + work_assignment.publish_submissions || (user && (submission.author == user || user.has_permission?('view_private_content', work_assignment.profile))) + end + + def self.is_submission?(content) + content && content.parent && content.parent.parent && content.parent.parent.kind_of?(WorkAssignmentPlugin::WorkAssignment) end def content_types @@ -24,4 +33,20 @@ class WorkAssignmentPlugin < Noosfero::Plugin !content.profile.members.include?(context.send(:user)) end + def content_viewer_controller_filters + block = lambda do + path = params[:page].join('/') + content = profile.articles.find_by_path(path) + + if WorkAssignmentPlugin.is_submission?(content) && !WorkAssignmentPlugin.can_download_submission?(user, content) + render_access_denied + end + end + + { :type => 'before_filter', + :method_name => 'work_assingment_only_admin_or_owner_download', + :options => {:only => 'view_page'}, + :block => block } + end + end diff --git a/plugins/work_assignment/lib/work_assignment_plugin/work_assignment.rb b/plugins/work_assignment/lib/work_assignment_plugin/work_assignment.rb index 9887193..a04d227 100644 --- a/plugins/work_assignment/lib/work_assignment_plugin/work_assignment.rb +++ b/plugins/work_assignment/lib/work_assignment_plugin/work_assignment.rb @@ -1,5 +1,7 @@ class WorkAssignmentPlugin::WorkAssignment < Folder + alias :submissions :children + def self.icon_name(article = nil) 'work-assignment' end diff --git a/plugins/work_assignment/test/functional/cms_controller_test.rb b/plugins/work_assignment/test/functional/cms_controller_test.rb new file mode 100644 index 0000000..7b9f94a --- /dev/null +++ b/plugins/work_assignment/test/functional/cms_controller_test.rb @@ -0,0 +1,34 @@ +require 'test_helper' +require 'cms_controller' + +# Re-raise errors caught by the controller. +class CmsController; def rescue_action(e) raise e end; end + +class CmsControllerTest < ActionController::TestCase + + def setup + @controller = CmsController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + @person = create_user('test_user').person + login_as :test_user + end + + attr_accessor :person + + should 'not allow non-members to upload submissions on work_assignment' do + organization = fast_create(Organization) + work_assignment = WorkAssignmentPlugin::WorkAssignment.create!(:name => 'Work Assignment', :profile => organization) + + get :upload_files, :profile => organization.identifier, :parent_id => work_assignment.id + assert_response :forbidden + assert_template 'access_denied.rhtml' + + organization.add_member(person) + + get :upload_files, :profile => organization.identifier, :parent_id => work_assignment.id + assert_response :success + end + +end + diff --git a/plugins/work_assignment/test/functional/content_viewer_controller_test.rb b/plugins/work_assignment/test/functional/content_viewer_controller_test.rb new file mode 100644 index 0000000..b3c4ece --- /dev/null +++ b/plugins/work_assignment/test/functional/content_viewer_controller_test.rb @@ -0,0 +1,41 @@ +require 'test_helper' +require 'content_viewer_controller' + +# Re-raise errors caught by the controller. +class ContentViewerController; def rescue_action(e) raise e end; end + +class ContentViewerControllerTest < ActionController::TestCase + + def setup + @controller = ContentViewerController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + + @organization = fast_create(Organization) + @work_assignment = WorkAssignmentPlugin::WorkAssignment.create!(:name => 'Work Assignment', :profile => @organization) + @person = create_user('test_user').person + @environment = @organization.environment + @environment.enable_plugin(WorkAssignmentPlugin) + @environment.save! + login_as(:test_user) + end + attr_reader :organization, :person, :work_assignment + + should 'can download work_assignment' do + random_member = fast_create(Person) + organization.add_member(random_member) + folder = work_assignment.find_or_create_author_folder(random_member) + submission = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :profile => organization, :parent => folder) + WorkAssignmentPlugin.stubs(:can_download_submission?).returns(false) + + get :view_page, :profile => organization.identifier, :page => submission.explode_path + assert_response :forbidden + assert_template 'access_denied.rhtml' + + WorkAssignmentPlugin.stubs(:can_download_submission?).returns(true) + + get :view_page, :profile => organization.identifier, :page => submission.explode_path + assert_response :success + end + +end diff --git a/plugins/work_assignment/test/unit/work_assingment_plugin_test.rb b/plugins/work_assignment/test/unit/work_assingment_plugin_test.rb new file mode 100644 index 0000000..c7c4898 --- /dev/null +++ b/plugins/work_assignment/test/unit/work_assingment_plugin_test.rb @@ -0,0 +1,57 @@ +require 'test_helper' + +class WorkAssignmentPluginTest < ActiveSupport::TestCase + should 'verify if a content is a work_assignment submission' do + organization = fast_create(Organization) + content = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :profile => organization) + assert !WorkAssignmentPlugin.is_submission?(content) + + work_assignment = WorkAssignmentPlugin::WorkAssignment.create!(:name => 'Work Assignment', :profile => organization) + content.parent = work_assignment + content.save! + assert !WorkAssignmentPlugin.is_submission?(content) + + author_folder = work_assignment.find_or_create_author_folder(fast_create(Person)) + content.parent = author_folder + content.save! + assert WorkAssignmentPlugin.is_submission?(content) + end + + should 'be able to download submission if work_assignment published submissions' do + submission = create_submission + assert !WorkAssignmentPlugin.can_download_submission?(nil, submission) + + work_assignment = submission.parent.parent + work_assignment.publish_submissions = true + work_assignment.save! + assert WorkAssignmentPlugin.can_download_submission?(nil, submission) + end + + should 'be able to download submission if the user is author of it' do + person = fast_create(Person) + submission = create_submission + assert !WorkAssignmentPlugin.can_download_submission?(person, submission) + + submission.author = person + submission.save! + assert WorkAssignmentPlugin.can_download_submission?(person, submission) + end + + should 'be able to download submission if the user has the view_private_content permission on the profile' do + person = fast_create(Person) + submission = create_submission + assert !WorkAssignmentPlugin.can_download_submission?(person, submission) + + moderator = create_user_with_permission('moderator', 'view_private_content', submission.profile) + assert WorkAssignmentPlugin.can_download_submission?(moderator, submission) + end + + private + + def create_submission + organization = fast_create(Organization) + work_assignment = WorkAssignmentPlugin::WorkAssignment.create!(:name => 'Work Assignment', :profile => organization) + author_folder = work_assignment.find_or_create_author_folder(fast_create(Person)) + UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :profile => organization, :parent => author_folder) + end +end diff --git a/test/functional/cms_controller_test.rb b/test/functional/cms_controller_test.rb index 19aa4e5..f4aa735 100644 --- a/test/functional/cms_controller_test.rb +++ b/test/functional/cms_controller_test.rb @@ -1566,6 +1566,18 @@ class CmsControllerTest < ActionController::TestCase assert_equal profile, a.author end + should 'not allow user upload files if he can not create on the parent folder' do + c = Community.create!(:name => 'test_comm', :identifier => 'test_comm') + u = create_user('test_user') + a = c.articles.create!(:name => 'test_article') + a.stubs(:allow_create?).with(u).returns(true) + login_as :test_user + + get :upload_files, :profile => c.identifier, :parent_id => a.id + assert_response :forbidden + assert_template 'access_denied.rhtml' + end + protected # FIXME this is to avoid adding an extra dependency for a proper JSON parser. -- libgit2 0.21.2