Commit eeb894292ed7d22db31af353e4ef7c9c391f9ad8

Authored by Leandro Santos
2 parents edcdbee8 a5e7b017

Merge branch 'master' into production

app/controllers/my_profile/tasks_controller.rb
1 class TasksController < MyProfileController 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 def index 6 def index
6 @filter_type = params[:filter_type].presence 7 @filter_type = params[:filter_type].presence
@@ -15,6 +16,8 @@ class TasksController &lt; MyProfileController @@ -15,6 +16,8 @@ class TasksController &lt; MyProfileController
15 @failed = params ? params[:failed] : {} 16 @failed = params ? params[:failed] : {}
16 17
17 @responsible_candidates = profile.members.by_role(profile.roles.reject {|r| !r.has_permission?('perform_task')}) if profile.organization? 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 end 21 end
19 22
20 def processed 23 def processed
app/models/environment.rb
@@ -75,7 +75,8 @@ class Environment &lt; ActiveRecord::Base @@ -75,7 +75,8 @@ class Environment &lt; ActiveRecord::Base
75 'edit_profile_design', 75 'edit_profile_design',
76 'manage_products', 76 'manage_products',
77 'manage_friends', 77 'manage_friends',
78 - 'perform_task' 78 + 'perform_task',
  79 + 'view_tasks'
79 ] 80 ]
80 ) 81 )
81 end 82 end
app/models/profile.rb
@@ -99,6 +99,7 @@ class Profile &lt; ActiveRecord::Base @@ -99,6 +99,7 @@ class Profile &lt; ActiveRecord::Base
99 'manage_friends' => N_('Manage friends'), 99 'manage_friends' => N_('Manage friends'),
100 'validate_enterprise' => N_('Validate enterprise'), 100 'validate_enterprise' => N_('Validate enterprise'),
101 'perform_task' => N_('Perform task'), 101 'perform_task' => N_('Perform task'),
  102 + 'view_tasks' => N_('View tasks'),
102 'moderate_comments' => N_('Moderate comments'), 103 'moderate_comments' => N_('Moderate comments'),
103 'edit_appearance' => N_('Edit appearance'), 104 'edit_appearance' => N_('Edit appearance'),
104 'view_private_content' => N_('View private content'), 105 'view_private_content' => N_('View private content'),
app/views/tasks/_task.html.erb
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 2
3 <%= render :partial => 'task_icon', :locals => {:task => task} %> 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 <div class="task_responsible"> 6 <div class="task_responsible">
7 <span class="label"><%= _('Assign to:') %></span> 7 <span class="label"><%= _('Assign to:') %></span>
8 <span> 8 <span>
@@ -12,8 +12,16 @@ @@ -12,8 +12,16 @@
12 </div> 12 </div>
13 <% end %> 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 <div class="task_decisions"> 22 <div class="task_decisions">
16 - <%= 23 + <% unless @view_only %>
  24 + <%=
17 labelled_radio_button(_("Accept"), "tasks[#{task.id}][decision]", 'finish', task.default_decision == 'accept', 25 labelled_radio_button(_("Accept"), "tasks[#{task.id}][decision]", 'finish', task.default_decision == 'accept',
18 :id => "decision-finish-#{task.id}", 26 :id => "decision-finish-#{task.id}",
19 :class => 'task_accept_radio', 27 :class => 'task_accept_radio',
@@ -29,7 +37,8 @@ @@ -29,7 +37,8 @@
29 :class => 'task_skip_radio', 37 :class => 'task_skip_radio',
30 :disabled => task.skip_disabled?, 38 :disabled => task.skip_disabled?,
31 :task_id => "#{task.id}") 39 :task_id => "#{task.id}")
32 - %> 40 + %>
  41 + <% end %>
33 </div><!-- class="task_decisions" --> 42 </div><!-- class="task_decisions" -->
34 43
35 <div class="task_date"><%= show_time(task.created_at) %></div> 44 <div class="task_date"><%= show_time(task.created_at) %></div>
app/views/tasks/index.html.erb
@@ -46,25 +46,30 @@ @@ -46,25 +46,30 @@
46 </p> 46 </p>
47 <% else %> 47 <% else %>
48 <%= form_tag :action => 'close' do%> 48 <%= form_tag :action => 'close' do%>
49 - <% button_bar do %> 49 + <% button_bar(:class => 'task-actions') do %>
50 <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %> 50 <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %>
51 <%# FIXME button('menu-mail', _('Send request'), :action => 'new') %> 51 <%# FIXME button('menu-mail', _('Send request'), :action => 'new') %>
52 <%= submit_button :save, _("Apply!") %> 52 <%= submit_button :save, _("Apply!") %>
53 <%= button(:edit, _('View processed tasks'), :action => 'processed') %> 53 <%= button(:edit, _('View processed tasks'), :action => 'processed') %>
54 <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %> 54 <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
55 - <% end %> 55 + <% end unless @view_only %>
56 56
57 <ul class='task-list'> 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 <div class="task_boxes"> 64 <div class="task_boxes">
63 <%= render :partial => 'task', :collection => @tasks %> 65 <%= render :partial => 'task', :collection => @tasks %>
64 </div> 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 </ul> 73 </ul>
69 74
70 <script> 75 <script>
@@ -76,13 +81,13 @@ @@ -76,13 +81,13 @@
76 81
77 <%= pagination_links(@tasks)%> 82 <%= pagination_links(@tasks)%>
78 83
79 - <% button_bar do %> 84 + <% button_bar(:class => 'task-actions') do %>
80 <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %> 85 <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %>
81 <%# FIXME button('menu-mail', _('Send request'), :action => 'new') %> 86 <%# FIXME button('menu-mail', _('Send request'), :action => 'new') %>
82 <%= submit_button :save, _("Apply!") %> 87 <%= submit_button :save, _("Apply!") %>
83 <%= button(:edit, _('View processed tasks'), :action => 'processed') %> 88 <%= button(:edit, _('View processed tasks'), :action => 'processed') %>
84 <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %> 89 <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
85 - <% end %> 90 + <% end unless @view_only %>
86 <% end %> 91 <% end %>
87 <% end %> 92 <% end %>
88 </p> 93 </p>
config/initializers/delayed_job_config.rb
@@ -23,3 +23,13 @@ end @@ -23,3 +23,13 @@ end
23 # end 23 # end
24 # alias_method_chain :handle_failed_job, :loggin 24 # alias_method_chain :handle_failed_job, :loggin
25 #end 25 #end
  26 +
  27 +# Chain delayed job's handle_failed_job method to do exception notification
  28 +Delayed::Worker.class_eval do
  29 + def handle_failed_job_with_notification job, error
  30 + handle_failed_job_without_notification job, error
  31 + ExceptionNotifier.notify_exception error, exception_recipients: NOOSFERO_CONF['exception_recipients'],
  32 + data: {job: job, handler: job.handler} rescue nil
  33 + end
  34 + alias_method_chain :handle_failed_job, :notification
  35 +end
po/pt/noosfero.po
@@ -13,8 +13,8 @@ msgid &quot;&quot; @@ -13,8 +13,8 @@ msgid &quot;&quot;
13 msgstr "" 13 msgstr ""
14 "Project-Id-Version: 1.1-166-gaf47713\n" 14 "Project-Id-Version: 1.1-166-gaf47713\n"
15 "POT-Creation-Date: 2015-06-01 17:26-0300\n" 15 "POT-Creation-Date: 2015-06-01 17:26-0300\n"
16 -"PO-Revision-Date: 2015-06-02 02:14+0200\n"  
17 -"Last-Translator: Eduardo Vital <vitaldu@gmail.com>\n" 16 +"PO-Revision-Date: 2015-06-02 19:44+0200\n"
  17 +"Last-Translator: Arthur Del Esposte <arthurmde@gmail.com>\n"
18 "Language-Team: Portuguese " 18 "Language-Team: Portuguese "
19 "<https://hosted.weblate.org/projects/noosfero/noosfero/pt/>\n" 19 "<https://hosted.weblate.org/projects/noosfero/noosfero/pt/>\n"
20 "Language: pt\n" 20 "Language: pt\n"
@@ -378,9 +378,8 @@ msgid &quot;Manage environment users&quot; @@ -378,9 +378,8 @@ msgid &quot;Manage environment users&quot;
378 msgstr "Gerenciar usuários do ambiente" 378 msgstr "Gerenciar usuários do ambiente"
379 379
380 #: app/models/environment.rb:32 380 #: app/models/environment.rb:32
381 -#, fuzzy  
382 msgid "Manage environment organizations" 381 msgid "Manage environment organizations"
383 -msgstr "Gerenciar ambiente de validadores" 382 +msgstr "Gerenciar organizações do ambiente"
384 383
385 #: app/models/environment.rb:33 384 #: app/models/environment.rb:33
386 msgid "Manage environment templates" 385 msgid "Manage environment templates"
@@ -697,14 +696,12 @@ msgstr &quot;&quot; @@ -697,14 +696,12 @@ msgstr &quot;&quot;
697 "podem ser feitas." 696 "podem ser feitas."
698 697
699 #: app/models/forum.rb:38 698 #: app/models/forum.rb:38
700 -#, fuzzy  
701 msgid "Logged users" 699 msgid "Logged users"
702 -msgstr "Identificado(a) como %s" 700 +msgstr "Usuários logados"
703 701
704 #: app/models/forum.rb:41 702 #: app/models/forum.rb:41
705 -#, fuzzy  
706 msgid "Me" 703 msgid "Me"
707 -msgstr "Masculino" 704 +msgstr "Eu"
708 705
709 #: app/models/forum.rb:42 app/models/block.rb:250 706 #: app/models/forum.rb:42 app/models/block.rb:250
710 #: app/helpers/application_helper.rb:563 707 #: app/helpers/application_helper.rb:563
@@ -712,9 +709,8 @@ msgid &quot;Friends&quot; @@ -712,9 +709,8 @@ msgid &quot;Friends&quot;
712 msgstr "Amigos" 709 msgstr "Amigos"
713 710
714 #: app/models/forum.rb:45 711 #: app/models/forum.rb:45
715 -#, fuzzy  
716 msgid "Administrators" 712 msgid "Administrators"
717 -msgstr "Administração" 713 +msgstr "Administradores"
718 714
719 #: app/models/forum.rb:46 app/models/block.rb:250 715 #: app/models/forum.rb:46 app/models/block.rb:250
720 #: app/helpers/profile_helper.rb:43 app/helpers/application_helper.rb:571 716 #: app/helpers/profile_helper.rb:43 app/helpers/application_helper.rb:571
@@ -1831,14 +1827,12 @@ msgid &quot;Article suggestion&quot; @@ -1831,14 +1827,12 @@ msgid &quot;Article suggestion&quot;
1831 msgstr "Sugestão de artigo" 1827 msgstr "Sugestão de artigo"
1832 1828
1833 #: app/models/suggest_article.rb:64 1829 #: app/models/suggest_article.rb:64
1834 -#, fuzzy  
1835 msgid "%{requestor} suggested the publication of the article: %{subject}." 1830 msgid "%{requestor} suggested the publication of the article: %{subject}."
1836 -msgstr "%{sender} sugeriu a publicação do artigo: %{subject}." 1831 +msgstr "%{requestor} sugeriu a publicação do artigo: %{subject}."
1837 1832
1838 #: app/models/suggest_article.rb:77 1833 #: app/models/suggest_article.rb:77
1839 -#, fuzzy  
1840 msgid "%{requestor} suggested the publication of the article: %{article}." 1834 msgid "%{requestor} suggested the publication of the article: %{article}."
1841 -msgstr "%{sender} sugeriu a publicação do artigo %{article}." 1835 +msgstr "%{requestor} sugeriu a publicação do artigo %{article}."
1842 1836
1843 #: app/models/rss_feed.rb:6 1837 #: app/models/rss_feed.rb:6
1844 msgid "RssFeed" 1838 msgid "RssFeed"
@@ -2221,11 +2215,11 @@ msgstr &quot;Não logado&quot; @@ -2221,11 +2215,11 @@ msgstr &quot;Não logado&quot;
2221 2215
2222 #: app/models/block.rb:256 2216 #: app/models/block.rb:256
2223 msgid "Can be modified" 2217 msgid "Can be modified"
2224 -msgstr "" 2218 +msgstr "Pode ser modificada"
2225 2219
2226 #: app/models/block.rb:257 2220 #: app/models/block.rb:257
2227 msgid "Cannot be modified" 2221 msgid "Cannot be modified"
2228 -msgstr "" 2222 +msgstr "Não pode ser modificada"
2229 2223
2230 #: app/models/block.rb:263 2224 #: app/models/block.rb:263
2231 msgid "Can be moved" 2225 msgid "Can be moved"
@@ -2563,9 +2557,8 @@ msgid &quot;Public&quot; @@ -2563,9 +2557,8 @@ msgid &quot;Public&quot;
2563 msgstr "Público" 2557 msgstr "Público"
2564 2558
2565 #: app/helpers/application_helper.rb:944 2559 #: app/helpers/application_helper.rb:944
2566 -#, fuzzy  
2567 msgid "Clone %s" 2560 msgid "Clone %s"
2568 -msgstr "Clonar" 2561 +msgstr "Clonar %s"
2569 2562
2570 #: app/helpers/application_helper.rb:958 2563 #: app/helpers/application_helper.rb:958
2571 msgid "Online Manual" 2564 msgid "Online Manual"
@@ -2842,21 +2835,20 @@ msgid &quot;See all connections&quot; @@ -2842,21 +2835,20 @@ msgid &quot;See all connections&quot;
2842 msgstr "Ver todas as conexões" 2835 msgstr "Ver todas as conexões"
2843 2836
2844 #: app/helpers/application_helper.rb:1518 2837 #: app/helpers/application_helper.rb:1518
2845 -#, fuzzy  
2846 msgid "Full screen" 2838 msgid "Full screen"
2847 -msgstr "Post completo" 2839 +msgstr "Tela cheia"
2848 2840
2849 #: app/helpers/application_helper.rb:1523 2841 #: app/helpers/application_helper.rb:1523
2850 msgid "Go to full screen mode" 2842 msgid "Go to full screen mode"
2851 -msgstr "" 2843 +msgstr "Ir para o modo tela cheia"
2852 2844
2853 #: app/helpers/application_helper.rb:1526 2845 #: app/helpers/application_helper.rb:1526
2854 msgid "Exit full screen" 2846 msgid "Exit full screen"
2855 -msgstr "" 2847 +msgstr "Sair da tela cheia"
2856 2848
2857 #: app/helpers/application_helper.rb:1532 2849 #: app/helpers/application_helper.rb:1532
2858 msgid "Exit full screen mode" 2850 msgid "Exit full screen mode"
2859 -msgstr "" 2851 +msgstr "Sair do modo tela cheia"
2860 2852
2861 #: app/helpers/manage_products_helper.rb:156 2853 #: app/helpers/manage_products_helper.rb:156
2862 #: app/views/manage_products/_display_category.html.erb:3 2854 #: app/views/manage_products/_display_category.html.erb:3
@@ -2988,9 +2980,8 @@ msgid &quot;search in all categories&quot; @@ -2988,9 +2980,8 @@ msgid &quot;search in all categories&quot;
2988 msgstr "procurar em todas as categorias" 2980 msgstr "procurar em todas as categorias"
2989 2981
2990 #: app/helpers/search_helper.rb:158 2982 #: app/helpers/search_helper.rb:158
2991 -#, fuzzy  
2992 msgid "Choose a template" 2983 msgid "Choose a template"
2993 -msgstr "O modelo \"%s\"" 2984 +msgstr "Escolha um template"
2994 2985
2995 #: app/helpers/boxes_helper.rb:106 2986 #: app/helpers/boxes_helper.rb:106
2996 msgid "This block is invisible. Your visitors will not see it." 2987 msgid "This block is invisible. Your visitors will not see it."
@@ -4081,9 +4072,8 @@ msgid &quot;Community fields not updated successfully.&quot; @@ -4081,9 +4072,8 @@ msgid &quot;Community fields not updated successfully.&quot;
4081 msgstr "Campos de comunidade não atualizados com sucesso." 4072 msgstr "Campos de comunidade não atualizados com sucesso."
4082 4073
4083 #: app/controllers/admin/organizations_controller.rb:7 4074 #: app/controllers/admin/organizations_controller.rb:7
4084 -#, fuzzy  
4085 msgid "Organization profiles" 4075 msgid "Organization profiles"
4086 -msgstr "Método de Aprovação de Organização" 4076 +msgstr "Perfis de organizações"
4087 4077
4088 #: app/controllers/admin/organizations_controller.rb:9 4078 #: app/controllers/admin/organizations_controller.rb:9
4089 #: app/views/tasks/index.html.erb:7 app/views/tasks/index.html.erb:34 4079 #: app/views/tasks/index.html.erb:7 app/views/tasks/index.html.erb:34
@@ -4093,9 +4083,8 @@ msgid &quot;All&quot; @@ -4093,9 +4083,8 @@ msgid &quot;All&quot;
4093 msgstr "Todos" 4083 msgstr "Todos"
4094 4084
4095 #: app/controllers/admin/organizations_controller.rb:33 4085 #: app/controllers/admin/organizations_controller.rb:33
4096 -#, fuzzy  
4097 msgid "%s enabled" 4086 msgid "%s enabled"
4098 -msgstr "%s não foi habilitado." 4087 +msgstr "%s habilitado"
4099 4088
4100 #: app/controllers/admin/organizations_controller.rb:35 4089 #: app/controllers/admin/organizations_controller.rb:35
4101 #, fuzzy 4090 #, fuzzy
@@ -4103,9 +4092,8 @@ msgid &quot;%s could not be enabled&quot; @@ -4103,9 +4092,8 @@ msgid &quot;%s could not be enabled&quot;
4103 msgstr "%s não pode ser enviado" 4092 msgstr "%s não pode ser enviado"
4104 4093
4105 #: app/controllers/admin/organizations_controller.rb:42 4094 #: app/controllers/admin/organizations_controller.rb:42
4106 -#, fuzzy  
4107 msgid "%s disabled" 4095 msgid "%s disabled"
4108 -msgstr "Desabilitado" 4096 +msgstr "%s desabilitado"
4109 4097
4110 #: app/controllers/admin/organizations_controller.rb:44 4098 #: app/controllers/admin/organizations_controller.rb:44
4111 #, fuzzy 4099 #, fuzzy
@@ -4568,9 +4556,8 @@ msgid &quot;Files&quot; @@ -4568,9 +4556,8 @@ msgid &quot;Files&quot;
4568 msgstr "Arquivos" 4556 msgstr "Arquivos"
4569 4557
4570 #: app/controllers/my_profile/profile_roles_controller.rb:52 4558 #: app/controllers/my_profile/profile_roles_controller.rb:52
4571 -#, fuzzy  
4572 msgid "Role successfuly removed!" 4559 msgid "Role successfuly removed!"
4573 -msgstr "Produto removido com sucesso" 4560 +msgstr "Papel removido com sucesso!"
4574 4561
4575 #: app/controllers/my_profile/profile_roles_controller.rb:54 4562 #: app/controllers/my_profile/profile_roles_controller.rb:54
4576 #, fuzzy 4563 #, fuzzy
@@ -4579,7 +4566,7 @@ msgstr &quot;Falhou em criar papel&quot; @@ -4579,7 +4566,7 @@ msgstr &quot;Falhou em criar papel&quot;
4579 4566
4580 #: app/controllers/my_profile/profile_roles_controller.rb:85 4567 #: app/controllers/my_profile/profile_roles_controller.rb:85
4581 msgid "Error" 4568 msgid "Error"
4582 -msgstr "" 4569 +msgstr "Erro"
4583 4570
4584 #: app/controllers/my_profile/tasks_controller.rb:28 4571 #: app/controllers/my_profile/tasks_controller.rb:28
4585 #, fuzzy 4572 #, fuzzy
test/functional/tasks_controller_test.rb
@@ -551,4 +551,114 @@ class TasksControllerTest &lt; ActionController::TestCase @@ -551,4 +551,114 @@ class TasksControllerTest &lt; ActionController::TestCase
551 assert !json_response['success'] 551 assert !json_response['success']
552 end 552 end
553 553
  554 + should 'list tasks for user with only view_tasks permission' do
  555 + community = fast_create(Community)
  556 + @controller.stubs(:profile).returns(community)
  557 + person = create_user_with_permission('taskviewer', 'view_tasks', community)
  558 + login_as person.user.login
  559 + get :index
  560 + assert_response :success
  561 + assert assigns(:view_only)
  562 + end
  563 +
  564 + should 'forbid user with only view_tasks permission to close a task' do
  565 + community = fast_create(Community)
  566 + @controller.stubs(:profile).returns(community)
  567 + person = create_user_with_permission('taskviewer', 'view_tasks', community)
  568 + login_as person.user.login
  569 + post :close
  570 + assert_response 403
  571 + end
  572 +
  573 + should 'hide tasks actions when user has only view_tasks permission' do
  574 + community = fast_create(Community)
  575 + @controller.stubs(:profile).returns(community)
  576 + person = create_user_with_permission('taskviewer', 'view_tasks', community)
  577 + login_as person.user.login
  578 +
  579 + Task.create!(:requestor => person, :target => community)
  580 + get :index
  581 +
  582 + assert_select '.task-actions', 0
  583 + end
  584 +
  585 + should 'display tasks actions when user has perform_task permission' do
  586 + community = fast_create(Community)
  587 + @controller.stubs(:profile).returns(community)
  588 + person = create_user_with_permission('taskperformer', 'perform_task', community)
  589 + login_as person.user.login
  590 +
  591 + Task.create!(:requestor => person, :target => community)
  592 + get :index
  593 +
  594 + assert_select '.task-actions', 2
  595 + end
  596 +
  597 + should 'hide decision selector when user has only view_tasks permission' do
  598 + community = fast_create(Community)
  599 + @controller.stubs(:profile).returns(community)
  600 + person = create_user_with_permission('taskviewer', 'view_tasks', community)
  601 + login_as person.user.login
  602 +
  603 + Task.create!(:requestor => person, :target => community)
  604 + get :index
  605 +
  606 + assert_select '#up-set-all-tasks-to', 0
  607 + assert_select '#down-set-all-tasks-to', 0
  608 + end
  609 +
  610 + should 'display decision selector when user has perform_task permission' do
  611 + community = fast_create(Community)
  612 + @controller.stubs(:profile).returns(community)
  613 + person = create_user_with_permission('taskperformer', 'perform_task', community)
  614 + login_as person.user.login
  615 +
  616 + Task.create!(:requestor => person, :target => community)
  617 + get :index
  618 +
  619 + assert_select '#up-set-all-tasks-to'
  620 + assert_select '#down-set-all-tasks-to'
  621 + end
  622 +
  623 + should 'hide decision buttons when user has only view_tasks permission' do
  624 + community = fast_create(Community)
  625 + @controller.stubs(:profile).returns(community)
  626 + person = create_user_with_permission('taskviewer', 'view_tasks', community)
  627 + login_as person.user.login
  628 +
  629 + task = Task.create!(:requestor => person, :target => community)
  630 + get :index
  631 +
  632 + assert_select "#decision-finish-#{task.id}", 0
  633 + assert_select "#decision-cancel-#{task.id}", 0
  634 + assert_select "#decision-skip-#{task.id}", 0
  635 + end
  636 +
  637 + should 'display decision buttons when user has perform_task permission' do
  638 + community = fast_create(Community)
  639 + @controller.stubs(:profile).returns(community)
  640 + person = create_user_with_permission('taskperformer', 'perform_task', community)
  641 + login_as person.user.login
  642 +
  643 + task = Task.create!(:requestor => person, :target => community)
  644 + get :index
  645 +
  646 + assert_select "#decision-finish-#{task.id}"
  647 + assert_select "#decision-cancel-#{task.id}"
  648 + assert_select "#decision-skip-#{task.id}"
  649 + end
  650 +
  651 + should 'hide responsive selection when user has only view_tasks permission' do
  652 + community = fast_create(Community)
  653 + @controller.stubs(:profile).returns(community)
  654 + person = create_user_with_permission('taskviewer', 'view_tasks', community)
  655 + login_as person.user.login
  656 +
  657 + task = Task.create!(:requestor => person, :target => community, :responsible => person)
  658 + get :index
  659 +
  660 + assert_select ".task_responsible select", 0
  661 + assert_select ".task_responsible .value"
  662 + end
  663 +
554 end 664 end
vendor/plugins/access_control/lib/permission_check.rb
@@ -19,7 +19,7 @@ module PermissionCheck @@ -19,7 +19,7 @@ module PermissionCheck
19 before_filter actions do |c| 19 before_filter actions do |c|
20 target = target_method.kind_of?(Symbol) ? c.send(target_method) : target_method 20 target = target_method.kind_of?(Symbol) ? c.send(target_method) : target_method
21 accessor = accessor_method.kind_of?(Symbol) ? c.send(accessor_method) : accessor_method 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 c.class.render_access_denied(c) && false 23 c.class.render_access_denied(c) && false
24 end 24 end
25 end 25 end
vendor/plugins/access_control/test/permission_check_test.rb
@@ -28,9 +28,20 @@ class PermissionCheckTest &lt; ActionController::TestCase @@ -28,9 +28,20 @@ class PermissionCheckTest &lt; ActionController::TestCase
28 end 28 end
29 29
30 def test_try_render_shared_access_denied_view 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 AccessControlTestController.access_denied_template_path 33 AccessControlTestController.access_denied_template_path
34 end 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 end 47 end
vendor/plugins/access_control/test/test_helper.rb
@@ -41,6 +41,8 @@ class AccessControlTestController &lt; ApplicationController @@ -41,6 +41,8 @@ class AccessControlTestController &lt; ApplicationController
41 include PermissionCheck 41 include PermissionCheck
42 protect 'see_index', 'global', :user, :only => :index 42 protect 'see_index', 'global', :user, :only => :index
43 protect 'do_some_stuff', :resource, :user, :only => :other_stuff 43 protect 'do_some_stuff', :resource, :user, :only => :other_stuff
  44 + protect ['permission1', 'permission2'], :resource, :user, :only => :stuff_with_multiple_permission
  45 +
44 def index 46 def index
45 render :text => 'test controller' 47 render :text => 'test controller'
46 end 48 end
@@ -49,6 +51,10 @@ class AccessControlTestController &lt; ApplicationController @@ -49,6 +51,10 @@ class AccessControlTestController &lt; ApplicationController
49 render :text => 'test stuff' 51 render :text => 'test stuff'
50 end 52 end
51 53
  54 + def stuff_with_multiple_permission
  55 + render :text => 'multiple permission'
  56 + end
  57 +
52 protected 58 protected
53 def user 59 def user
54 AccessControlTestAccessor.find(params[:user]) if params[:user] 60 AccessControlTestAccessor.find(params[:user]) if params[:user]
vendor/plugins/delayed_job/lib/delayed/backend/base.rb
@@ -73,9 +73,8 @@ module Delayed @@ -73,9 +73,8 @@ module Delayed
73 ParseObjectFromYaml = /\!ruby\/\w+\:([^\s]+)/ 73 ParseObjectFromYaml = /\!ruby\/\w+\:([^\s]+)/
74 74
75 def name 75 def name
76 - @name ||= payload_object.respond_to?(:display_name) ?  
77 - payload_object.display_name :  
78 - payload_object.class.name 76 + obj = payload_object
  77 + @name ||= obj.respond_to?(:display_name) ? obj.display_name : obj.class.name
79 rescue DeserializationError 78 rescue DeserializationError
80 ParseObjectFromYaml.match(handler)[1] 79 ParseObjectFromYaml.match(handler)[1]
81 end 80 end
vendor/plugins/monkey_patches/init.rb
1 -require File.join(File.dirname(__FILE__), 'attachment_fu_validates_attachment/init')  
2 -require File.join(File.dirname(__FILE__), 'attachment_fu/init')  
3 -require File.join(File.dirname(__FILE__), 'white_list_sanitizer_unescape_before_reescape/init') 1 +require_relative 'attachment_fu_validates_attachment/init'
  2 +require_relative 'attachment_fu/init'
  3 +require_relative 'white_list_sanitizer_unescape_before_reescape/init'
vendor/plugins/monkey_patches/rescue_delayed_job_crashes/init.rb
@@ -1,57 +0,0 @@ @@ -1,57 +0,0 @@
1 -Delayed::Worker.module_eval do  
2 - # based on https://groups.google.com/forum/#!topic/delayed_job/ZGMUFFppNgs  
3 - class Delayed::Worker::ExceptionNotification < ActionMailer::Base  
4 - def mail job, error  
5 - environment = Environment.default  
6 -  
7 - recipients NOOSFERO_CONF['exception_recipients']  
8 - from environment.noreply_email  
9 - reply_to environment.noreply_email  
10 - subject "[#{environment.name}] DelayedJob ##{job.id}: #{error.message}"  
11 - body render(:text => "  
12 -Job:  
13 -#{job.inspect}  
14 -  
15 -Handler:  
16 -#{job.handler}  
17 -  
18 -Backtrace:  
19 -#{error.backtrace.join("\n")}  
20 - ")  
21 - end  
22 - end  
23 -  
24 - def handle_failed_job_with_notification(job, error)  
25 - Delayed::Worker::ExceptionNotification.deliver_mail job, error if NOOSFERO_CONF['exception_recipients'].present?  
26 - handle_failed_job_without_notification job, error  
27 - end  
28 - alias_method_chain :handle_failed_job, :notification  
29 -  
30 - def handle_failed_job_with_rescue(job, error)  
31 - handle_failed_job_without_rescue(job, error)  
32 - rescue => e # don't crash here  
33 - end  
34 - alias_method_chain :handle_failed_job, :rescue  
35 -  
36 - protected  
37 -  
38 - # This code must be replicated because there is no other way to pass the job  
39 - # through and use alias_method_chain as we used on the previous method  
40 - def reserve_and_run_one_job  
41 - # We get up to 5 jobs from the db. In case we cannot get exclusive access to a job we try the next.  
42 - # this leads to a more even distribution of jobs across the worker processes  
43 - job = Delayed::Job.find_available(name, 5, self.class.max_run_time).detect do |job|  
44 - if job.lock_exclusively!(self.class.max_run_time, name)  
45 - say "acquired lock on #{job.name}"  
46 - true  
47 - else  
48 - say "failed to acquire exclusive lock for #{job.name}", Logger::WARN  
49 - false  
50 - end  
51 - end  
52 -  
53 - run(job) if job  
54 - rescue => e  
55 - handle_failed_job(job, e)  
56 - end  
57 -end