diff options
| author | Vlatka Pavisic | 2017-01-16 15:21:11 +0100 | 
|---|---|---|
| committer | Vlatka Pavisic | 2017-01-16 15:21:11 +0100 | 
| commit | 307f808e2c812bccccd1c6246ca6b8583be4ef40 (patch) | |
| tree | 694dc741ecef8f502097f5c79e5217f933bd727b | |
| parent | 9e69db1f517d15ab52cd169e3a5774d9071c3630 (diff) | |
| download | chouette-core-307f808e2c812bccccd1c6246ca6b8583be4ef40.tar.bz2 | |
Refs #2399 : User routes permissions
| -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 | 
