Commit bdaf45c2917613b64fbdd5ecb0458cfe3078cdbc
Exists in
master
and in
12 other branches
Merge branch 'view_tasks_permission' into 'master'
New permission 'view_tasks' that allow only tasks visualization See merge request !588
Showing
9 changed files
with
164 additions
and
18 deletions
Show diff stats
app/controllers/my_profile/tasks_controller.rb
| 1 | 1 | class TasksController < MyProfileController |
| 2 | 2 | |
| 3 | - protect 'perform_task', :profile | |
| 3 | + protect [:perform_task, :view_tasks], :profile, :only => [:index] | |
| 4 | + protect :perform_task, :profile, :except => [:index] | |
| 4 | 5 | |
| 5 | 6 | def index |
| 6 | 7 | @filter_type = params[:filter_type].presence |
| ... | ... | @@ -15,6 +16,8 @@ class TasksController < MyProfileController |
| 15 | 16 | @failed = params ? params[:failed] : {} |
| 16 | 17 | |
| 17 | 18 | @responsible_candidates = profile.members.by_role(profile.roles.reject {|r| !r.has_permission?('perform_task')}) if profile.organization? |
| 19 | + | |
| 20 | + @view_only = !current_person.has_permission?(:perform_task, profile) | |
| 18 | 21 | end |
| 19 | 22 | |
| 20 | 23 | def processed | ... | ... |
app/models/environment.rb
app/models/profile.rb
| ... | ... | @@ -71,6 +71,7 @@ class Profile < ActiveRecord::Base |
| 71 | 71 | 'manage_friends' => N_('Manage friends'), |
| 72 | 72 | 'validate_enterprise' => N_('Validate enterprise'), |
| 73 | 73 | 'perform_task' => N_('Perform task'), |
| 74 | + 'view_tasks' => N_('View tasks'), | |
| 74 | 75 | 'moderate_comments' => N_('Moderate comments'), |
| 75 | 76 | 'edit_appearance' => N_('Edit appearance'), |
| 76 | 77 | 'view_private_content' => N_('View private content'), | ... | ... |
app/views/tasks/_task.html.erb
| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | |
| 3 | 3 | <%= render :partial => 'task_icon', :locals => {:task => task} %> |
| 4 | 4 | |
| 5 | - <% if profile.organization? && @responsible_candidates.present? %> | |
| 5 | + <% if !@view_only && profile.organization? && @responsible_candidates.present? %> | |
| 6 | 6 | <div class="task_responsible"> |
| 7 | 7 | <span class="label"><%= _('Assign to:') %></span> |
| 8 | 8 | <span> |
| ... | ... | @@ -12,8 +12,16 @@ |
| 12 | 12 | </div> |
| 13 | 13 | <% end %> |
| 14 | 14 | |
| 15 | + <% if @view_only && task.responsible.present? %> | |
| 16 | + <div class="task_responsible"> | |
| 17 | + <span class="label"><%= _('Assigned to:') %></span> | |
| 18 | + <span class="value"><%= task.responsible.name %></span> | |
| 19 | + </div> | |
| 20 | + <% end %> | |
| 21 | + | |
| 15 | 22 | <div class="task_decisions"> |
| 16 | - <%= | |
| 23 | + <% unless @view_only %> | |
| 24 | + <%= | |
| 17 | 25 | labelled_radio_button(_("Accept"), "tasks[#{task.id}][decision]", 'finish', task.default_decision == 'accept', |
| 18 | 26 | :id => "decision-finish-#{task.id}", |
| 19 | 27 | :class => 'task_accept_radio', |
| ... | ... | @@ -29,7 +37,8 @@ |
| 29 | 37 | :class => 'task_skip_radio', |
| 30 | 38 | :disabled => task.skip_disabled?, |
| 31 | 39 | :task_id => "#{task.id}") |
| 32 | - %> | |
| 40 | + %> | |
| 41 | + <% end %> | |
| 33 | 42 | </div><!-- class="task_decisions" --> |
| 34 | 43 | |
| 35 | 44 | <div class="task_date"><%= show_time(task.created_at) %></div> | ... | ... |
app/views/tasks/index.html.erb
| ... | ... | @@ -46,36 +46,41 @@ |
| 46 | 46 | </p> |
| 47 | 47 | <% else %> |
| 48 | 48 | <%= form_tag :action => 'close' do%> |
| 49 | - <% button_bar do %> | |
| 49 | + <% button_bar(:class => 'task-actions') do %> | |
| 50 | 50 | <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %> |
| 51 | 51 | <%# FIXME button('menu-mail', _('Send request'), :action => 'new') %> |
| 52 | 52 | <%= submit_button :save, _("Apply!") %> |
| 53 | 53 | <%= button(:edit, _('View processed tasks'), :action => 'processed') %> |
| 54 | 54 | <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %> |
| 55 | - <% end %> | |
| 55 | + <% end unless @view_only %> | |
| 56 | 56 | |
| 57 | 57 | <ul class='task-list'> |
| 58 | - <p> | |
| 59 | - <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "up-set-all-tasks-to") %> | |
| 60 | - </p> | |
| 58 | + <% unless @view_only %> | |
| 59 | + <p> | |
| 60 | + <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "up-set-all-tasks-to") %> | |
| 61 | + </p> | |
| 62 | + <% end %> | |
| 61 | 63 | |
| 62 | 64 | <div class="task_boxes"> |
| 63 | 65 | <%= render :partial => 'task', :collection => @tasks %> |
| 64 | 66 | </div> |
| 65 | - <p> | |
| 66 | - <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "down-set-all-tasks-to") %> | |
| 67 | - </p> | |
| 67 | + | |
| 68 | + <% unless @view_only %> | |
| 69 | + <p> | |
| 70 | + <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "down-set-all-tasks-to") %> | |
| 71 | + </p> | |
| 72 | + <% end %> | |
| 68 | 73 | </ul> |
| 69 | 74 | |
| 70 | 75 | <%= pagination_links(@tasks)%> |
| 71 | 76 | |
| 72 | - <% button_bar do %> | |
| 77 | + <% button_bar(:class => 'task-actions') do %> | |
| 73 | 78 | <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %> |
| 74 | 79 | <%# FIXME button('menu-mail', _('Send request'), :action => 'new') %> |
| 75 | 80 | <%= submit_button :save, _("Apply!") %> |
| 76 | 81 | <%= button(:edit, _('View processed tasks'), :action => 'processed') %> |
| 77 | 82 | <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %> |
| 78 | - <% end %> | |
| 83 | + <% end unless @view_only %> | |
| 79 | 84 | <% end %> |
| 80 | 85 | <% end %> |
| 81 | 86 | </p> | ... | ... |
test/functional/tasks_controller_test.rb
| ... | ... | @@ -520,4 +520,114 @@ class TasksControllerTest < ActionController::TestCase |
| 520 | 520 | assert !json_response['success'] |
| 521 | 521 | end |
| 522 | 522 | |
| 523 | + should 'list tasks for user with only view_tasks permission' do | |
| 524 | + community = fast_create(Community) | |
| 525 | + @controller.stubs(:profile).returns(community) | |
| 526 | + person = create_user_with_permission('taskviewer', 'view_tasks', community) | |
| 527 | + login_as person.user.login | |
| 528 | + get :index | |
| 529 | + assert_response :success | |
| 530 | + assert assigns(:view_only) | |
| 531 | + end | |
| 532 | + | |
| 533 | + should 'forbid user with only view_tasks permission to close a task' do | |
| 534 | + community = fast_create(Community) | |
| 535 | + @controller.stubs(:profile).returns(community) | |
| 536 | + person = create_user_with_permission('taskviewer', 'view_tasks', community) | |
| 537 | + login_as person.user.login | |
| 538 | + post :close | |
| 539 | + assert_response 403 | |
| 540 | + end | |
| 541 | + | |
| 542 | + should 'hide tasks actions when user has only view_tasks permission' do | |
| 543 | + community = fast_create(Community) | |
| 544 | + @controller.stubs(:profile).returns(community) | |
| 545 | + person = create_user_with_permission('taskviewer', 'view_tasks', community) | |
| 546 | + login_as person.user.login | |
| 547 | + | |
| 548 | + Task.create!(:requestor => person, :target => community) | |
| 549 | + get :index | |
| 550 | + | |
| 551 | + assert_select '.task-actions', 0 | |
| 552 | + end | |
| 553 | + | |
| 554 | + should 'display tasks actions when user has perform_task permission' do | |
| 555 | + community = fast_create(Community) | |
| 556 | + @controller.stubs(:profile).returns(community) | |
| 557 | + person = create_user_with_permission('taskperformer', 'perform_task', community) | |
| 558 | + login_as person.user.login | |
| 559 | + | |
| 560 | + Task.create!(:requestor => person, :target => community) | |
| 561 | + get :index | |
| 562 | + | |
| 563 | + assert_select '.task-actions', 2 | |
| 564 | + end | |
| 565 | + | |
| 566 | + should 'hide decision selector when user has only view_tasks permission' do | |
| 567 | + community = fast_create(Community) | |
| 568 | + @controller.stubs(:profile).returns(community) | |
| 569 | + person = create_user_with_permission('taskviewer', 'view_tasks', community) | |
| 570 | + login_as person.user.login | |
| 571 | + | |
| 572 | + Task.create!(:requestor => person, :target => community) | |
| 573 | + get :index | |
| 574 | + | |
| 575 | + assert_select '#up-set-all-tasks-to', 0 | |
| 576 | + assert_select '#down-set-all-tasks-to', 0 | |
| 577 | + end | |
| 578 | + | |
| 579 | + should 'display decision selector when user has perform_task permission' do | |
| 580 | + community = fast_create(Community) | |
| 581 | + @controller.stubs(:profile).returns(community) | |
| 582 | + person = create_user_with_permission('taskperformer', 'perform_task', community) | |
| 583 | + login_as person.user.login | |
| 584 | + | |
| 585 | + Task.create!(:requestor => person, :target => community) | |
| 586 | + get :index | |
| 587 | + | |
| 588 | + assert_select '#up-set-all-tasks-to' | |
| 589 | + assert_select '#down-set-all-tasks-to' | |
| 590 | + end | |
| 591 | + | |
| 592 | + should 'hide decision buttons when user has only view_tasks permission' do | |
| 593 | + community = fast_create(Community) | |
| 594 | + @controller.stubs(:profile).returns(community) | |
| 595 | + person = create_user_with_permission('taskviewer', 'view_tasks', community) | |
| 596 | + login_as person.user.login | |
| 597 | + | |
| 598 | + task = Task.create!(:requestor => person, :target => community) | |
| 599 | + get :index | |
| 600 | + | |
| 601 | + assert_select "#decision-finish-#{task.id}", 0 | |
| 602 | + assert_select "#decision-cancel-#{task.id}", 0 | |
| 603 | + assert_select "#decision-skip-#{task.id}", 0 | |
| 604 | + end | |
| 605 | + | |
| 606 | + should 'display decision buttons when user has perform_task permission' do | |
| 607 | + community = fast_create(Community) | |
| 608 | + @controller.stubs(:profile).returns(community) | |
| 609 | + person = create_user_with_permission('taskperformer', 'perform_task', community) | |
| 610 | + login_as person.user.login | |
| 611 | + | |
| 612 | + task = Task.create!(:requestor => person, :target => community) | |
| 613 | + get :index | |
| 614 | + | |
| 615 | + assert_select "#decision-finish-#{task.id}" | |
| 616 | + assert_select "#decision-cancel-#{task.id}" | |
| 617 | + assert_select "#decision-skip-#{task.id}" | |
| 618 | + end | |
| 619 | + | |
| 620 | + should 'hide responsive selection when user has only view_tasks permission' do | |
| 621 | + community = fast_create(Community) | |
| 622 | + @controller.stubs(:profile).returns(community) | |
| 623 | + person = create_user_with_permission('taskviewer', 'view_tasks', community) | |
| 624 | + login_as person.user.login | |
| 625 | + | |
| 626 | + task = Task.create!(:requestor => person, :target => community, :responsible => person) | |
| 627 | + get :index | |
| 628 | + | |
| 629 | + assert_select ".task_responsible select", 0 | |
| 630 | + assert_select ".task_responsible .value" | |
| 631 | + end | |
| 632 | + | |
| 523 | 633 | end | ... | ... |
vendor/plugins/access_control/lib/permission_check.rb
| ... | ... | @@ -19,7 +19,7 @@ module PermissionCheck |
| 19 | 19 | before_filter actions do |c| |
| 20 | 20 | target = target_method.kind_of?(Symbol) ? c.send(target_method) : target_method |
| 21 | 21 | accessor = accessor_method.kind_of?(Symbol) ? c.send(accessor_method) : accessor_method |
| 22 | - unless accessor && accessor.has_permission?(permission.to_s, target) | |
| 22 | + unless Array.wrap(permission).map {|p| accessor && accessor.has_permission?(p.to_s, target)}.any? | |
| 23 | 23 | c.class.render_access_denied(c) && false |
| 24 | 24 | end |
| 25 | 25 | end | ... | ... |
vendor/plugins/access_control/test/permission_check_test.rb
| ... | ... | @@ -28,9 +28,20 @@ class PermissionCheckTest < ActionController::TestCase |
| 28 | 28 | end |
| 29 | 29 | |
| 30 | 30 | def test_try_render_shared_access_denied_view |
| 31 | - File.expects(:exists?).with(File.join(Rails.root, 'app', 'views', 'access_control', 'access_denied.rhtml')) | |
| 32 | - File.expects(:exists?).with(File.join(Rails.root, 'app', 'views', 'shared', 'access_denied.rhtml')) | |
| 31 | + File.expects(:exists?).with(File.join(Rails.root, 'app', 'views', 'access_control', 'access_denied.html.erb')) | |
| 32 | + File.expects(:exists?).with(File.join(Rails.root, 'app', 'views', 'shared', 'access_denied.html.erb')) | |
| 33 | 33 | AccessControlTestController.access_denied_template_path |
| 34 | 34 | end |
| 35 | 35 | |
| 36 | + def test_allow_access_to_user_with_one_of_multiple_permissions | |
| 37 | + user = AccessControlTestAccessor.create!(:name => 'other_user') | |
| 38 | + role = Role.create!(:name => 'other_role', :permissions => ['permission1']) | |
| 39 | + resource = AccessControlTestResource.create!(:name => 'some_resource') | |
| 40 | + assert user.add_role(role, resource) | |
| 41 | + assert user.has_permission?('permission1', resource) | |
| 42 | + | |
| 43 | + get :stuff_with_multiple_permission, :user => user.id, :resource => resource.id | |
| 44 | + assert_response :success | |
| 45 | + end | |
| 46 | + | |
| 36 | 47 | end | ... | ... |
vendor/plugins/access_control/test/test_helper.rb
| ... | ... | @@ -41,6 +41,8 @@ class AccessControlTestController < ApplicationController |
| 41 | 41 | include PermissionCheck |
| 42 | 42 | protect 'see_index', 'global', :user, :only => :index |
| 43 | 43 | protect 'do_some_stuff', :resource, :user, :only => :other_stuff |
| 44 | + protect ['permission1', 'permission2'], :resource, :user, :only => :stuff_with_multiple_permission | |
| 45 | + | |
| 44 | 46 | def index |
| 45 | 47 | render :text => 'test controller' |
| 46 | 48 | end |
| ... | ... | @@ -49,6 +51,10 @@ class AccessControlTestController < ApplicationController |
| 49 | 51 | render :text => 'test stuff' |
| 50 | 52 | end |
| 51 | 53 | |
| 54 | + def stuff_with_multiple_permission | |
| 55 | + render :text => 'multiple permission' | |
| 56 | + end | |
| 57 | + | |
| 52 | 58 | protected |
| 53 | 59 | def user |
| 54 | 60 | AccessControlTestAccessor.find(params[:user]) if params[:user] | ... | ... |