diff options
| -rw-r--r-- | app/controllers/routes_controller.rb | 7 | ||||
| -rw-r--r-- | app/models/user.rb | 4 | ||||
| -rw-r--r-- | app/policies/route_policy.rb | 22 | ||||
| -rw-r--r-- | app/views/referential_lines/_reflines_routes.html.slim | 16 | ||||
| -rw-r--r-- | app/views/referential_lines/show.html.slim | 3 | ||||
| -rw-r--r-- | app/views/routes/_route.html.slim | 10 | ||||
| -rw-r--r-- | app/views/routes/show.html.slim | 24 | ||||
| -rw-r--r-- | db/migrate/20170116140623_give_routes_permissions_to_users.rb | 8 | ||||
| -rw-r--r-- | db/schema.rb | 2 | ||||
| -rw-r--r-- | spec/features/routes_spec.rb | 88 | ||||
| -rw-r--r-- | spec/support/devise.rb | 4 |
11 files changed, 163 insertions, 25 deletions
diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb index 89d2ddef4..be6329006 100644 --- a/app/controllers/routes_controller.rb +++ b/app/controllers/routes_controller.rb @@ -10,10 +10,11 @@ class RoutesController < ChouetteController end before_action :define_candidate_opposite_routes, only: [:new, :edit, :create, :update] + before_action :check_policy, only: [:edit, :update, :destroy] def index index! do |format| - format.html { redirect_to referential_line_path(@referential,@line) } + format.html { redirect_to referential_line_path(@referential, @line) } end end @@ -85,6 +86,10 @@ class RoutesController < ChouetteController end end + def check_policy + authorize resource + end + private def route_params diff --git a/app/models/user.rb b/app/models/user.rb index 93b1f8f21..3debf37dc 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -66,6 +66,10 @@ class User < ActiveRecord::Base end end + def has_permission?(permission) + permissions && permissions.include?(permission) + end + private # remove organisation and referentials if last user of it diff --git a/app/policies/route_policy.rb b/app/policies/route_policy.rb new file mode 100644 index 000000000..232706d8f --- /dev/null +++ b/app/policies/route_policy.rb @@ -0,0 +1,22 @@ +class RoutePolicy < ApplicationPolicy + class Scope < Scope + def resolve + scope + end + end + + def create? + user.has_permission?('routes.create') + end + + def edit? + user.has_permission?('routes.edit') + end + + def destroy? + user.has_permission?('routes.destroy') + end + + def update? ; edit? end + def new? ; create? end +end diff --git a/app/views/referential_lines/_reflines_routes.html.slim b/app/views/referential_lines/_reflines_routes.html.slim index 77b350fa6..8dcae73b5 100644 --- a/app/views/referential_lines/_reflines_routes.html.slim +++ b/app/views/referential_lines/_reflines_routes.html.slim @@ -9,7 +9,7 @@ th.text-center = @routes.human_attribute_name(:wayback) th.text-center = @routes.human_attribute_name(:opposite_route) th.text-center = "Actions" - + tbody - @routes.each do |route| tr @@ -21,14 +21,16 @@ = route.opposite_route.name - else = "Aucune séquence d'arrêts associée en sens opposé" - + td.text-center .btn.btn-group.btn-group-sm = link_to [@referential, @line, route], class: 'btn btn-default preview', title: "#{Chouette::Route.model_name.human.capitalize} #{route.name}" do span.fa.fa-eye - - = link_to edit_referential_line_route_path(@referential, @line, route), class: 'btn btn-default' do - span.fa.fa-pencil - = link_to referential_line_route_path(@referential, @line, route), method: :delete, :data => {:confirm => t('routes.actions.destroy_confirm')}, class: 'btn btn-danger' do - span.fa.fa-trash-o + - if policy(route).edit? + = link_to edit_referential_line_route_path(@referential, @line, route), class: 'btn btn-default' do + span.fa.fa-pencil + + - if policy(route).destroy? + = link_to referential_line_route_path(@referential, @line, route), method: :delete, :data => {:confirm => t('routes.actions.destroy_confirm')}, class: 'btn btn-danger' do + span.fa.fa-trash-o diff --git a/app/views/referential_lines/show.html.slim b/app/views/referential_lines/show.html.slim index ad455862d..5c8e1b32d 100644 --- a/app/views/referential_lines/show.html.slim +++ b/app/views/referential_lines/show.html.slim @@ -139,6 +139,7 @@ p.after_map - if !@line.hub_restricted? || (@line.hub_restricted? && @line.routes.size < 2) / FIXME #825 li - = link_to t('routes.actions.new'), new_referential_line_route_path(@referential, @line), class: 'add' + - if policy(Chouette::Route).create? + = link_to t('routes.actions.new'), new_referential_line_route_path(@referential, @line), class: 'add' = creation_tag(@line) diff --git a/app/views/routes/_route.html.slim b/app/views/routes/_route.html.slim index 251c92000..e273bfcfd 100644 --- a/app/views/routes/_route.html.slim +++ b/app/views/routes/_route.html.slim @@ -2,11 +2,13 @@ .panel-heading .panel-title.clearfix .btn-group.btn-group-sm.pull-right - = link_to edit_referential_line_route_path(@referential, @line, route), class: 'btn btn-default' do - span.fa.fa-pencil + - if policy(route).edit? + = link_to edit_referential_line_route_path(@referential, @line, route), class: 'btn btn-default' do + span.fa.fa-pencil - = link_to referential_line_route_path(@referential, @line, route), method: :delete, :data => {:confirm => t('routes.actions.destroy_confirm')}, class: 'btn btn-danger' do - span.fa.fa-trash-o + - if policy(route).destroy? + = link_to referential_line_route_path(@referential, @line, route), method: :delete, :data => {:confirm => t('routes.actions.destroy_confirm')}, class: 'btn btn-danger' do + span.fa.fa-trash-o h5 = link_to [@referential, @line, route], class: 'preview', title: "#{Chouette::Route.model_name.human.capitalize} #{route.name}" do diff --git a/app/views/routes/show.html.slim b/app/views/routes/show.html.slim index 3f0e22006..6a1d16c66 100644 --- a/app/views/routes/show.html.slim +++ b/app/views/routes/show.html.slim @@ -15,11 +15,11 @@ / p / label = "#{@route.human_attribute_name(:number)} : " / = " #{@route.number}" - / + / / p / label = "#{@route.human_attribute_name(:comment)} : " / = " #{@route.comment}" - / + / / p / label = "#{@route.human_attribute_name(:direction)} : " / - if @route.direction @@ -47,14 +47,14 @@ p.after_map .panel-heading h4.panel-title strong = t('.stop_points') - + .list-group - @route.stop_points.each do |point| - if point.stop_area.zip_code && point.stop_area.city_name - linktxt = "#{point.stop_area.name}, #{point.stop_area.zip_code} #{point.stop_area.city_name}" - else - linktxt = "#{point.stop_area.name}" - + = link_to [@referential, point.stop_area], { style: 'display: table;width: 100%;', class: 'list-group-item', title: "Voir l'arrêt '#{linktxt}'" } do div style='display: table-cell;vertical-align: middle;' div style='display: inline-block;width: 10%;vertical-align: middle;text-align: right;' @@ -67,7 +67,7 @@ p.after_map .panel-heading h4.panel-title strong = t('.journey_patterns') - + .list-group - @route.journey_patterns.each do |journey_pattern| .list-group-item.clearfix title="#{t('journey_patterns.journey_pattern.stop_count', count: journey_pattern.stop_points.count, route_count: @route.stop_points.count)} | #{t('journey_patterns.journey_pattern.vehicle_journeys_count', count: journey_pattern.vehicle_journeys.count)}" @@ -85,16 +85,22 @@ p.after_map ul.dropdown-menu li = link_to 'Voir', [@referential, @line, @route, journey_pattern], title: "#{Chouette::JourneyPattern.model_name.human.capitalize} #{journey_name(journey_pattern)}" li = link_to 'Supprimer', referential_line_route_journey_pattern_path(@referential, @line, @route, journey_pattern), method: :delete, data: {confirm: t('journey_patterns.actions.destroy_confirm')} - + / .panel-body / .journey_patterns.paginated_content / = paginated_content( @route.journey_patterns, "journey_patterns/journey_pattern") - content_for :sidebar do ul.actions - li = link_to t('routes.actions.new'), new_referential_line_route_path(@referential, @line), class: 'add' - li = link_to t('routes.actions.edit'), edit_referential_line_route_path(@referential, @line, @route), class: 'edit' - li = link_to t('routes.actions.destroy'), referential_line_route_path(@referential, @line, @route), method: :delete, :data => {:confirm => t('routes.actions.destroy_confirm')}, class: 'remove' + li + - if policy(@route).create? + = link_to t('routes.actions.new'), new_referential_line_route_path(@referential, @line), class: 'add' + li + - if policy(@route).edit? + = link_to t('routes.actions.edit'), edit_referential_line_route_path(@referential, @line, @route), class: 'edit' + li + - if policy(@route).destroy? + = link_to t('routes.actions.destroy'), referential_line_route_path(@referential, @line, @route), method: :delete, :data => {:confirm => t('routes.actions.destroy_confirm')}, class: 'remove' ul.actions - if @route.stop_points.size >= 2 diff --git a/db/migrate/20170116140623_give_routes_permissions_to_users.rb b/db/migrate/20170116140623_give_routes_permissions_to_users.rb new file mode 100644 index 000000000..22a08e738 --- /dev/null +++ b/db/migrate/20170116140623_give_routes_permissions_to_users.rb @@ -0,0 +1,8 @@ +class GiveRoutesPermissionsToUsers < ActiveRecord::Migration + def change + User.find_each do |user| + user.permissions =['routes.create', 'routes.edit', 'routes.destroy'] + user.save! + end + end +end diff --git a/db/schema.rb b/db/schema.rb index fe0ddec32..880597573 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170113155639) do +ActiveRecord::Schema.define(version: 20170116140623) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" diff --git a/spec/features/routes_spec.rb b/spec/features/routes_spec.rb index 5aea98c90..70d32c777 100644 --- a/spec/features/routes_spec.rb +++ b/spec/features/routes_spec.rb @@ -54,4 +54,92 @@ describe "Routes", :type => :feature do end end + describe 'referential line show' do + context 'user has permission to edit routes' do + it 'shows edit buttons for routes' do + visit referential_line_path(referential, line) + expect(page).to have_css('span.fa.fa-pencil') + end + end + + context 'user does not have permission to edit routes' do + it 'does not show edit buttons for routes' do + @user.update_attribute(:permissions, ['routes.create', 'routes.destroy']) + visit referential_line_path(referential, line) + expect(page).not_to have_css('span.fa.fa-pencil') + end + end + + context 'user has permission to create routes' do + it 'shows link to a create route page' do + visit referential_line_path(referential, line) + expect(page).to have_content(I18n.t('routes.actions.new')) + end + end + + context 'user does not have permission to create routes' do + it 'does not show link to a create route page' do + @user.update_attribute(:permissions, ['routes.edit', 'routes.destroy']) + visit referential_line_path(referential, line) + expect(page).not_to have_content(I18n.t('routes.actions.new')) + end + end + + context 'user has permission to destroy routes' do + it 'shows destroy buttons for routes' do + visit referential_line_path(referential, line) + expect(page).to have_css('span.fa.fa-trash-o') + end + end + + context 'user does not have permission to destroy routes' do + it 'does not show destroy buttons for routes' do + @user.update_attribute(:permissions, ['routes.edit', 'routes.create']) + visit referential_line_path(referential, line) + expect(page).not_to have_css('span.fa.fa-trash-o') + end + end + end end + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spec/support/devise.rb b/spec/support/devise.rb index 2258fefbb..ae166d284 100644 --- a/spec/support/devise.rb +++ b/spec/support/devise.rb @@ -3,7 +3,7 @@ module DeviseRequestHelper def login_user organisation = Organisation.where(:code => "first").first_or_create(attributes_for(:organisation)) - @user ||= create(:user, :organisation => organisation) + @user ||= create(:user, :organisation => organisation, :permissions => ['routes.create', 'routes.edit', 'routes.destroy']) login_as @user, :scope => :user # post_via_redirect user_session_path, 'user[email]' => @user.email, 'user[password]' => @user.password end @@ -34,7 +34,7 @@ module DeviseControllerHelper before(:each) do @request.env["devise.mapping"] = Devise.mappings[:user] organisation = Organisation.where(:code => "first").first_or_create(attributes_for(:organisation)) - user = create(:user, :organisation => organisation) + user = create(:user, :organisation => organisation, :permissions => ['routes.create', 'routes.edit', 'routes.destroy']) sign_in user end end |
