[noosfero/noosfero][master] 3 commits: Allow more than one permission when define access control with 'protect'

Leandro Nunes gitlab at gitlab.com
Tue Jun 2 20:34:53 BRT 2015


Leandro Nunes pushed to branch master at Noosfero / noosfero


Commits:
7018f3aa by Victor Costa at 2015-06-01T15:51:48Z
Allow more than one permission when define access control with 'protect'

- - - - -
d01c42a2 by Victor Costa at 2015-06-01T16:51:16Z
New permission 'view_tasks' that allow only tasks visualization

- - - - -
bdaf45c2 by Leandro Nunes at 2015-06-02T23:34:43Z
Merge branch 'view_tasks_permission' into 'master'

New permission 'view_tasks' that allow only tasks visualization

See merge request !588

- - - - -


9 changed files:

- app/controllers/my_profile/tasks_controller.rb
- app/models/environment.rb
- app/models/profile.rb
- app/views/tasks/_task.html.erb
- app/views/tasks/index.html.erb
- test/functional/tasks_controller_test.rb
- vendor/plugins/access_control/lib/permission_check.rb
- vendor/plugins/access_control/test/permission_check_test.rb
- vendor/plugins/access_control/test/test_helper.rb


Changes:

=====================================
app/controllers/my_profile/tasks_controller.rb
=====================================
--- a/app/controllers/my_profile/tasks_controller.rb
+++ b/app/controllers/my_profile/tasks_controller.rb
@@ -1,6 +1,7 @@
 class TasksController < MyProfileController
 
-  protect 'perform_task', :profile
+  protect [:perform_task, :view_tasks], :profile, :only => [:index]
+  protect :perform_task, :profile, :except => [:index]
 
   def index
     @filter_type = params[:filter_type].presence
@@ -15,6 +16,8 @@ class TasksController < MyProfileController
     @failed = params ? params[:failed] : {}
 
     @responsible_candidates = profile.members.by_role(profile.roles.reject {|r| !r.has_permission?('perform_task')}) if profile.organization?
+
+    @view_only = !current_person.has_permission?(:perform_task, profile)
   end
 
   def processed


=====================================
app/models/environment.rb
=====================================
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -75,7 +75,8 @@ class Environment < ActiveRecord::Base
         'edit_profile_design',
         'manage_products',
         'manage_friends',
-        'perform_task'
+        'perform_task',
+        'view_tasks'
       ]
     )
   end


=====================================
app/models/profile.rb
=====================================
--- a/app/models/profile.rb
+++ b/app/models/profile.rb
@@ -71,6 +71,7 @@ class Profile < ActiveRecord::Base
     'manage_friends'       => N_('Manage friends'),
     'validate_enterprise'  => N_('Validate enterprise'),
     'perform_task'         => N_('Perform task'),
+    'view_tasks'           => N_('View tasks'),
     'moderate_comments'    => N_('Moderate comments'),
     'edit_appearance'      => N_('Edit appearance'),
     'view_private_content' => N_('View private content'),


=====================================
app/views/tasks/_task.html.erb
=====================================
--- a/app/views/tasks/_task.html.erb
+++ b/app/views/tasks/_task.html.erb
@@ -2,7 +2,7 @@
 
   <%= render :partial => 'task_icon', :locals => {:task => task} %>
 
-  <% if profile.organization? && @responsible_candidates.present? %>
+  <% if !@view_only && profile.organization? && @responsible_candidates.present? %>
     <div class="task_responsible">
       <span class="label"><%= _('Assign to:') %></span>
       <span>
@@ -12,8 +12,16 @@
     </div>
   <% end %>
 
+  <% if @view_only && task.responsible.present? %>
+    <div class="task_responsible">
+      <span class="label"><%= _('Assigned to:') %></span>
+      <span class="value"><%= task.responsible.name %></span>
+    </div>
+  <% end %>
+
   <div class="task_decisions">
-    <%=
+    <% unless @view_only %>
+      <%=
         labelled_radio_button(_("Accept"), "tasks[#{task.id}][decision]", 'finish', task.default_decision == 'accept',
                               :id => "decision-finish-#{task.id}",
                               :class => 'task_accept_radio',
@@ -29,7 +37,8 @@
                               :class => 'task_skip_radio',
                               :disabled => task.skip_disabled?,
                               :task_id => "#{task.id}")
-    %>
+      %>
+    <% end %>
   </div><!-- class="task_decisions" -->
 
   <div class="task_date"><%= show_time(task.created_at) %></div>


=====================================
app/views/tasks/index.html.erb
=====================================
--- a/app/views/tasks/index.html.erb
+++ b/app/views/tasks/index.html.erb
@@ -46,36 +46,41 @@
   </p>
 <% else %>
   <%= form_tag :action => 'close' do%>
-    <% button_bar do %>
+    <% button_bar(:class => 'task-actions') do %>
       <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %>
       <%# FIXME button('menu-mail',  _('Send request'), :action => 'new') %>
       <%= submit_button :save, _("Apply!") %>
       <%= button(:edit, _('View processed tasks'), :action => 'processed') %>
       <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
-    <% end %>
+    <% end unless @view_only %>
 
     <ul class='task-list'>
-      <p>
-      <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "up-set-all-tasks-to") %>
-      </p>
+      <% unless @view_only %>
+        <p>
+        <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "up-set-all-tasks-to") %>
+        </p>
+      <% end %>
 
       <div class="task_boxes">
         <%= render :partial => 'task', :collection => @tasks %>
       </div>
-      <p>
-      <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "down-set-all-tasks-to") %>
-      </p>
+
+      <% unless @view_only %>
+        <p>
+        <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "down-set-all-tasks-to") %>
+        </p>
+      <% end %>
     </ul>
 
     <%= pagination_links(@tasks)%>
 
-    <% button_bar do %>
+    <% button_bar(:class => 'task-actions') do %>
       <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %>
       <%# FIXME button('menu-mail',  _('Send request'), :action => 'new') %>
       <%= submit_button :save, _("Apply!") %>
       <%= button(:edit, _('View processed tasks'), :action => 'processed') %>
       <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
-    <% end %>
+    <% end unless @view_only %>
   <% end %>
 <% end %>
 </p>


=====================================
test/functional/tasks_controller_test.rb
=====================================
--- a/test/functional/tasks_controller_test.rb
+++ b/test/functional/tasks_controller_test.rb
@@ -520,4 +520,114 @@ class TasksControllerTest < ActionController::TestCase
     assert !json_response['success']
   end
 
+  should 'list tasks for user with only view_tasks permission' do
+    community = fast_create(Community)
+    @controller.stubs(:profile).returns(community)
+    person = create_user_with_permission('taskviewer', 'view_tasks', community)
+    login_as person.user.login
+    get :index
+    assert_response :success
+    assert assigns(:view_only)
+  end
+
+  should 'forbid user with only view_tasks permission to close a task' do
+    community = fast_create(Community)
+    @controller.stubs(:profile).returns(community)
+    person = create_user_with_permission('taskviewer', 'view_tasks', community)
+    login_as person.user.login
+    post :close
+    assert_response 403
+  end
+
+  should 'hide tasks actions when user has only view_tasks permission' do
+    community = fast_create(Community)
+    @controller.stubs(:profile).returns(community)
+    person = create_user_with_permission('taskviewer', 'view_tasks', community)
+    login_as person.user.login
+
+    Task.create!(:requestor => person, :target => community)
+    get :index
+
+    assert_select '.task-actions', 0
+  end
+
+  should 'display tasks actions when user has perform_task permission' do
+    community = fast_create(Community)
+    @controller.stubs(:profile).returns(community)
+    person = create_user_with_permission('taskperformer', 'perform_task', community)
+    login_as person.user.login
+
+    Task.create!(:requestor => person, :target => community)
+    get :index
+
+    assert_select '.task-actions', 2
+  end
+
+  should 'hide decision selector when user has only view_tasks permission' do
+    community = fast_create(Community)
+    @controller.stubs(:profile).returns(community)
+    person = create_user_with_permission('taskviewer', 'view_tasks', community)
+    login_as person.user.login
+
+    Task.create!(:requestor => person, :target => community)
+    get :index
+
+    assert_select '#up-set-all-tasks-to', 0
+    assert_select '#down-set-all-tasks-to', 0
+  end
+
+  should 'display decision selector when user has perform_task permission' do
+    community = fast_create(Community)
+    @controller.stubs(:profile).returns(community)
+    person = create_user_with_permission('taskperformer', 'perform_task', community)
+    login_as person.user.login
+
+    Task.create!(:requestor => person, :target => community)
+    get :index
+
+    assert_select '#up-set-all-tasks-to'
+    assert_select '#down-set-all-tasks-to'
+  end
+
+  should 'hide decision buttons when user has only view_tasks permission' do
+    community = fast_create(Community)
+    @controller.stubs(:profile).returns(community)
+    person = create_user_with_permission('taskviewer', 'view_tasks', community)
+    login_as person.user.login
+
+    task = Task.create!(:requestor => person, :target => community)
+    get :index
+
+    assert_select "#decision-finish-#{task.id}", 0
+    assert_select "#decision-cancel-#{task.id}", 0
+    assert_select "#decision-skip-#{task.id}", 0
+  end
+
+  should 'display decision buttons when user has perform_task permission' do
+    community = fast_create(Community)
+    @controller.stubs(:profile).returns(community)
+    person = create_user_with_permission('taskperformer', 'perform_task', community)
+    login_as person.user.login
+
+    task = Task.create!(:requestor => person, :target => community)
+    get :index
+
+    assert_select "#decision-finish-#{task.id}"
+    assert_select "#decision-cancel-#{task.id}"
+    assert_select "#decision-skip-#{task.id}"
+  end
+
+  should 'hide responsive selection when user has only view_tasks permission' do
+    community = fast_create(Community)
+    @controller.stubs(:profile).returns(community)
+    person = create_user_with_permission('taskviewer', 'view_tasks', community)
+    login_as person.user.login
+
+    task = Task.create!(:requestor => person, :target => community, :responsible => person)
+    get :index
+
+    assert_select ".task_responsible select", 0
+    assert_select ".task_responsible .value"
+  end
+
 end


=====================================
vendor/plugins/access_control/lib/permission_check.rb
=====================================
--- a/vendor/plugins/access_control/lib/permission_check.rb
+++ b/vendor/plugins/access_control/lib/permission_check.rb
@@ -19,7 +19,7 @@ module PermissionCheck
       before_filter actions do |c|
           target = target_method.kind_of?(Symbol) ? c.send(target_method) : target_method
           accessor = accessor_method.kind_of?(Symbol) ? c.send(accessor_method) : accessor_method
-          unless accessor && accessor.has_permission?(permission.to_s, target)
+          unless Array.wrap(permission).map {|p| accessor && accessor.has_permission?(p.to_s, target)}.any?
             c.class.render_access_denied(c) && false
           end
       end


=====================================
vendor/plugins/access_control/test/permission_check_test.rb
=====================================
--- a/vendor/plugins/access_control/test/permission_check_test.rb
+++ b/vendor/plugins/access_control/test/permission_check_test.rb
@@ -28,9 +28,20 @@ class PermissionCheckTest < ActionController::TestCase
   end
 
   def test_try_render_shared_access_denied_view
-    File.expects(:exists?).with(File.join(Rails.root, 'app', 'views', 'access_control', 'access_denied.rhtml'))
-    File.expects(:exists?).with(File.join(Rails.root, 'app', 'views', 'shared', 'access_denied.rhtml'))
+    File.expects(:exists?).with(File.join(Rails.root, 'app', 'views', 'access_control', 'access_denied.html.erb'))
+    File.expects(:exists?).with(File.join(Rails.root, 'app', 'views', 'shared', 'access_denied.html.erb'))
     AccessControlTestController.access_denied_template_path
   end
 
+  def test_allow_access_to_user_with_one_of_multiple_permissions
+    user = AccessControlTestAccessor.create!(:name => 'other_user')
+    role = Role.create!(:name => 'other_role', :permissions => ['permission1'])
+    resource = AccessControlTestResource.create!(:name => 'some_resource')
+    assert user.add_role(role, resource)
+    assert user.has_permission?('permission1', resource)
+
+    get :stuff_with_multiple_permission, :user => user.id, :resource => resource.id
+    assert_response :success
+  end
+
 end


=====================================
vendor/plugins/access_control/test/test_helper.rb
=====================================
--- a/vendor/plugins/access_control/test/test_helper.rb
+++ b/vendor/plugins/access_control/test/test_helper.rb
@@ -41,6 +41,8 @@ class AccessControlTestController < ApplicationController
   include PermissionCheck
   protect 'see_index', 'global', :user,  :only => :index
   protect 'do_some_stuff', :resource, :user, :only => :other_stuff
+  protect ['permission1', 'permission2'], :resource, :user, :only => :stuff_with_multiple_permission
+
   def index
      render :text => 'test controller'
   end
@@ -49,6 +51,10 @@ class AccessControlTestController < ApplicationController
     render :text => 'test stuff'
   end
 
+  def stuff_with_multiple_permission
+    render :text => 'multiple permission'
+  end
+
 protected
   def user
     AccessControlTestAccessor.find(params[:user]) if params[:user]



View it on GitLab: https://gitlab.com/noosfero/noosfero/compare/790467ebf58f06764c6d327e708613a64e4656a0...bdaf45c2917613b64fbdd5ecb0458cfe3078cdbc
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listas.softwarelivre.org/pipermail/noosfero-dev/attachments/20150602/1c735692/attachment-0001.html>


More information about the Noosfero-dev mailing list