Commit bdaf45c2917613b64fbdd5ecb0458cfe3078cdbc
Exists in
master
and in
25 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] | ... | ... |