Merge pull request #942 from nishanthvijayan/fix-roles-authorization
Fix authorization issues with Roles
This commit is contained in:
commit
0a5ba7a204
6 changed files with 77 additions and 51 deletions
|
|
@ -2,11 +2,13 @@ module Admin
|
||||||
class RolesController < Admin::BaseController
|
class RolesController < Admin::BaseController
|
||||||
load_and_authorize_resource :conference, find_by: :short_title
|
load_and_authorize_resource :conference, find_by: :short_title
|
||||||
before_action :set_selection
|
before_action :set_selection
|
||||||
|
authorize_resource :role, except: :index
|
||||||
# Show flash message with ajax calls
|
# Show flash message with ajax calls
|
||||||
after_action :prepare_unobtrusive_flash, only: :toggle_user
|
after_action :prepare_unobtrusive_flash, only: :toggle_user
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@roles = Role.where(resource: @conference)
|
@roles = Role.where(resource: @conference)
|
||||||
|
authorize! :index, @role
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
|
|
||||||
|
|
@ -278,7 +278,7 @@ module ApplicationHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def can_manage_volunteers(conference)
|
def can_manage_volunteers(conference)
|
||||||
if (current_user.has_role? :organizer, conference) || (current_user.has_role? :volunteer_coordinator, conference)
|
if (current_user.has_role? :organizer, conference) || (current_user.has_role? :volunteers_coordinator, conference)
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ class Ability
|
||||||
# user.is_organizer? or user.has_role? :organizer
|
# user.is_organizer? or user.has_role? :organizer
|
||||||
# user.is_cfp_of? Conference or user.has_role? :cfp, Conference
|
# user.is_cfp_of? Conference or user.has_role? :cfp, Conference
|
||||||
# user.is_info_desk_of? Conference
|
# user.is_info_desk_of? Conference
|
||||||
# user.is_volunteer_coordinator_of? Conference
|
# user.is_volunteers_coordinator_of? Conference
|
||||||
# user.is_attendee_of? Conference
|
# user.is_attendee_of? Conference
|
||||||
# The following is wrong because a user will only have 'cfp' role for a specific conference
|
# The following is wrong because a user will only have 'cfp' role for a specific conference
|
||||||
# user.is_cfp? # This is always false
|
# user.is_cfp? # This is always false
|
||||||
|
|
@ -104,7 +104,7 @@ class Ability
|
||||||
signed_in_with_organizer_role(user) if user.has_role? :organizer, :any
|
signed_in_with_organizer_role(user) if user.has_role? :organizer, :any
|
||||||
signed_in_with_cfp_role(user) if user.has_role? :cfp, :any
|
signed_in_with_cfp_role(user) if user.has_role? :cfp, :any
|
||||||
signed_in_with_info_desk_role(user) if user.has_role? :info_desk, :any
|
signed_in_with_info_desk_role(user) if user.has_role? :info_desk, :any
|
||||||
signed_in_with_volunteers_coordinator_role(user) if user.has_role? :volunteer_coordinator, :any
|
signed_in_with_volunteers_coordinator_role(user) if user.has_role? :volunteers_coordinator, :any
|
||||||
|
|
||||||
# for users with any role
|
# for users with any role
|
||||||
can :access, Admin
|
can :access, Admin
|
||||||
|
|
@ -123,9 +123,7 @@ class Ability
|
||||||
|
|
||||||
def signed_in_with_organizer_role(user)
|
def signed_in_with_organizer_role(user)
|
||||||
# ids of all the conferences for which the user has the 'organizer' role
|
# ids of all the conferences for which the user has the 'organizer' role
|
||||||
conf_ids_for_organizer = []
|
conf_ids_for_organizer = Conference.with_role(:organizer, user).pluck(:id)
|
||||||
conf_ids_for_organizer =
|
|
||||||
Conference.with_role(:organizer, user).pluck(:id) if user.has_role? :organizer, :any
|
|
||||||
|
|
||||||
can [:new, :create], Conference if user.has_role?(:organizer, :any)
|
can [:new, :create], Conference if user.has_role?(:organizer, :any)
|
||||||
can :manage, Conference, id: conf_ids_for_organizer
|
can :manage, Conference, id: conf_ids_for_organizer
|
||||||
|
|
@ -162,24 +160,15 @@ class Ability
|
||||||
commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_organizer).pluck(:id)).pluck(:id)
|
commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_organizer).pluck(:id)).pluck(:id)
|
||||||
|
|
||||||
# Abilities for Role (Conference resource)
|
# Abilities for Role (Conference resource)
|
||||||
can :index, Role
|
can [:index, :show], Role
|
||||||
can :manage, Role do |role|
|
can [:edit, :update, :toggle_user], Role do |role|
|
||||||
role.resource_type == 'Conference' && (conf_ids_for_organizer.include? role.resource_id)
|
role.resource_type == 'Conference' && (conf_ids_for_organizer.include? role.resource_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Can add or remove users from role, when user has that same role for the conference
|
|
||||||
# Eg. If you are member of the CfP team, you can add more CfP team members (add users to the role 'CfP')
|
|
||||||
can :toggle_user, Role do |role|
|
|
||||||
role.resource_type == 'Conference' &&
|
|
||||||
(Conference.with_role(role.name.parameterize.underscore.to_sym, user).pluck(:id).include? role.resource_id)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def signed_in_with_cfp_role(user)
|
def signed_in_with_cfp_role(user)
|
||||||
# ids of all the conferences for which the user has the 'cfp' role
|
# ids of all the conferences for which the user has the 'cfp' role
|
||||||
conf_ids_for_cfp = []
|
conf_ids_for_cfp = Conference.with_role(:cfp, user).pluck(:id)
|
||||||
conf_ids_for_cfp =
|
|
||||||
Conference.with_role(:cfp, user).pluck(:id) if user.has_role? :cfp, :any
|
|
||||||
|
|
||||||
can :manage, Event, program: { conference_id: conf_ids_for_cfp }
|
can :manage, Event, program: { conference_id: conf_ids_for_cfp }
|
||||||
can :manage, EventType, program: { conference_id: conf_ids_for_cfp }
|
can :manage, EventType, program: { conference_id: conf_ids_for_cfp }
|
||||||
|
|
@ -196,66 +185,52 @@ class Ability
|
||||||
commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_cfp).pluck(:id)).pluck(:id)
|
commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_cfp).pluck(:id)).pluck(:id)
|
||||||
|
|
||||||
# Abilities for Role (Conference resource)
|
# Abilities for Role (Conference resource)
|
||||||
can :index, Role
|
can [:index, :show], Role
|
||||||
|
|
||||||
can :manage, Role do |role|
|
|
||||||
role.resource_type == 'Conference' && (conf_ids_for_cfp.include? role.resource_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Can add or remove users from role, when user has that same role for the conference
|
# Can add or remove users from role, when user has that same role for the conference
|
||||||
# Eg. If you are member of the CfP team, you can add more CfP team members (add users to the role 'CfP')
|
# Eg. If you are member of the CfP team, you can add more CfP team members (add users to the role 'CfP')
|
||||||
can :toggle_user, Role do |role|
|
can :toggle_user, Role do |role|
|
||||||
role.resource_type == 'Conference' &&
|
role.resource_type == 'Conference' && role.name == 'cfp' &&
|
||||||
(Conference.with_role(role.name.parameterize.underscore.to_sym, user).pluck(:id).include? role.resource_id)
|
(Conference.with_role(:cfp, user).pluck(:id).include? role.resource_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def signed_in_with_info_desk_role(user)
|
def signed_in_with_info_desk_role(user)
|
||||||
# ids of all the conferences for which the user has the 'info_desk' role
|
# ids of all the conferences for which the user has the 'info_desk' role
|
||||||
conf_ids_for_info_desk = []
|
conf_ids_for_info_desk = Conference.with_role(:info_desk, user).pluck(:id)
|
||||||
conf_ids_for_info_desk =
|
|
||||||
Conference.with_role(:info_desk, user).pluck(:id) if user.has_role? :info_desk, :any
|
|
||||||
|
|
||||||
can :manage, Registration, conference_id: conf_ids_for_info_desk
|
can :manage, Registration, conference_id: conf_ids_for_info_desk
|
||||||
can :manage, Question, conference_id: conf_ids_for_info_desk
|
can :manage, Question, conference_id: conf_ids_for_info_desk
|
||||||
can :manage, Question do |question|
|
can :manage, Question do |question|
|
||||||
!(question.conferences.pluck(:id) & conf_ids_for_info_desk).empty?
|
!(question.conferences.pluck(:id) & conf_ids_for_info_desk).empty?
|
||||||
end
|
end
|
||||||
# Abilities for Role (Conference resource)
|
|
||||||
can :index, Role
|
|
||||||
|
|
||||||
can :manage, Role do |role|
|
# Abilities for Role (Conference resource)
|
||||||
role.resource_type == 'Conference' && (conf_ids_for_info_desk.include? role.resource_id)
|
can [:index, :show], Role
|
||||||
end
|
|
||||||
|
|
||||||
# Can add or remove users from role, when user has that same role for the conference
|
# Can add or remove users from role, when user has that same role for the conference
|
||||||
# Eg. If you are member of the CfP team, you can add more CfP team members (add users to the role 'CfP')
|
# Eg. If you are member of the CfP team, you can add more CfP team members (add users to the role 'CfP')
|
||||||
can :toggle_user, Role do |role|
|
can :toggle_user, Role do |role|
|
||||||
role.resource_type == 'Conference' &&
|
role.resource_type == 'Conference' && role.name == 'info_desk' &&
|
||||||
(Conference.with_role(role.name.parameterize.underscore.to_sym, user).pluck(:id).include? role.resource_id)
|
(Conference.with_role(:info_desk, user).pluck(:id).include? role.resource_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def signed_in_with_volunteers_coordinator_role(user)
|
def signed_in_with_volunteers_coordinator_role(user)
|
||||||
# ids of all the conferences for which the user has the 'volunteers_coordinator' role
|
# ids of all the conferences for which the user has the 'volunteers_coordinator' role
|
||||||
conf_ids_for_volunteers_coordinator = []
|
conf_ids_for_volunteers_coordinator = Conference.with_role(:volunteers_coordinator, user).pluck(:id)
|
||||||
conf_ids_for_volunteers_coordinator =
|
|
||||||
Conference.with_role(:volunteer_coordinator, user).pluck(:id) if user.has_role? :volunteer_coordinator, :any
|
|
||||||
|
|
||||||
can :manage, Vposition, conference_id: conf_ids_for_volunteers_coordinator
|
can :manage, Vposition, conference_id: conf_ids_for_volunteers_coordinator
|
||||||
can :manage, Vday, conference_id: conf_ids_for_volunteers_coordinator
|
can :manage, Vday, conference_id: conf_ids_for_volunteers_coordinator
|
||||||
# Abilities for Role (Conference resource)
|
|
||||||
can :index, Role
|
|
||||||
|
|
||||||
can :manage, Role do |role|
|
# Abilities for Role (Conference resource)
|
||||||
role.resource_type == 'Conference' && (conf_ids_for_volunteers_coordinator.include? role.resource_id)
|
can [:index, :show], Role
|
||||||
end
|
|
||||||
|
|
||||||
# Can add or remove users from role, when user has that same role for the conference
|
# Can add or remove users from role, when user has that same role for the conference
|
||||||
# Eg. If you are member of the CfP team, you can add more CfP team members (add users to the role 'CfP')
|
# Eg. If you are member of the CfP team, you can add more CfP team members (add users to the role 'CfP')
|
||||||
can :toggle_user, Role do |role|
|
can :toggle_user, Role do |role|
|
||||||
role.resource_type == 'Conference' &&
|
role.resource_type == 'Conference' && role.name == 'volunteers_coordinator' &&
|
||||||
(Conference.with_role(role.name.parameterize.underscore.to_sym, user).pluck(:id).include? role.resource_id)
|
(Conference.with_role(:volunteers_coordinator, user).pluck(:id).include? role.resource_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,18 @@
|
||||||
- if users.present?
|
- if users.present?
|
||||||
%table.table.table-striped.table-bordered.table-hover.datatable#users
|
%table.table.table-striped.table-bordered.table-hover.datatable#users
|
||||||
%thead
|
%thead
|
||||||
%th.col-md-1
|
- if ( can? :toggle_user, @role )
|
||||||
|
%th.col-md-1
|
||||||
%th ID
|
%th ID
|
||||||
%th Name
|
%th Name
|
||||||
%th Email
|
%th Email
|
||||||
%tbody
|
%tbody
|
||||||
- users.each do |user|
|
- users.each do |user|
|
||||||
%tr
|
%tr
|
||||||
%td.text-right
|
- if ( can? :toggle_user, @role )
|
||||||
= hidden_field_tag "role[user_ids][]", nil
|
%td.text-right
|
||||||
= check_box_tag @conference.short_title, @role.id, (@role.user_ids.include? user.id), method: :post, url: "/admin/conference/#{@conference.short_title}/roles/#{@role.name}/toggle_user?user[email]=#{user.email}&user[state]=", class: 'switch-checkbox', data: { size: 'small', off_color: 'warning', on_text: 'Yes', off_text: 'No' }
|
= hidden_field_tag "role[user_ids][]", nil
|
||||||
|
= check_box_tag @conference.short_title, @role.id, (@role.user_ids.include? user.id), method: :post, url: "/admin/conference/#{@conference.short_title}/roles/#{@role.name}/toggle_user?user[email]=#{user.email}&user[state]=", class: 'switch-checkbox', data: { size: 'small', off_color: 'warning', on_text: 'Yes', off_text: 'No' }
|
||||||
%td= user.id
|
%td= user.id
|
||||||
%td= user.name
|
%td= user.name
|
||||||
%td= user.email
|
%td= user.email
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,13 @@ feature 'Has correct abilities' do
|
||||||
let(:role_organizer) { Role.find_by(name: 'organizer', resource: conference1) }
|
let(:role_organizer) { Role.find_by(name: 'organizer', resource: conference1) }
|
||||||
let(:role_cfp) { Role.find_by(name: 'cfp', resource: conference2) }
|
let(:role_cfp) { Role.find_by(name: 'cfp', resource: conference2) }
|
||||||
let(:role_info_desk) { Role.find_by(name: 'info_desk', resource: conference3) }
|
let(:role_info_desk) { Role.find_by(name: 'info_desk', resource: conference3) }
|
||||||
let(:role_volunteer_coordinator) { Role.find_by(name: 'volunteers_coordinator', resource: conference4) }
|
let(:role_volunteers_coordinator) { Role.find_by(name: 'volunteers_coordinator', resource: conference4) }
|
||||||
|
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
let(:user_organizer) { create(:user, role_ids: [role_organizer.id]) }
|
let(:user_organizer) { create(:user, role_ids: [role_organizer.id]) }
|
||||||
let(:user_cfp) { create(:user, role_ids: [role_cfp.id]) }
|
let(:user_cfp) { create(:user, role_ids: [role_cfp.id]) }
|
||||||
let(:user_info_desk) { create(:user, role_ids: [role_info_desk.id]) }
|
let(:user_info_desk) { create(:user, role_ids: [role_info_desk.id]) }
|
||||||
let(:user_volunteer_coordinator) { create(:user, role_ids: [role_volunteer_coordinator.id]) }
|
let(:user_volunteers_coordinator) { create(:user, role_ids: [role_volunteers_coordinator.id]) }
|
||||||
|
|
||||||
scenario 'when user has no role' do
|
scenario 'when user has no role' do
|
||||||
sign_in user
|
sign_in user
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,34 @@ describe 'User' do
|
||||||
it{ should_not be_able_to(:destroy, my_venue) }
|
it{ should_not be_able_to(:destroy, my_venue) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
shared_examples 'user with any role' do
|
||||||
|
before do
|
||||||
|
@other_conference = create(:conference)
|
||||||
|
end
|
||||||
|
|
||||||
|
%w(organizer cfp info_desk volunteers_coordinator).each do |role|
|
||||||
|
it{ should_not be_able_to(:toggle_user, Role.find_by(name: role, resource: @other_conference)) }
|
||||||
|
it{ should_not be_able_to(:update, Role.find_by(name: role, resource: @other_conference)) }
|
||||||
|
it{ should_not be_able_to(:edit, Role.find_by(name: role, resource: @other_conference)) }
|
||||||
|
it{ should be_able_to(:show, Role.find_by(name: role, resource: @other_conference)) }
|
||||||
|
it{ should be_able_to(:index, Role.find_by(name: role, resource: @other_conference)) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
shared_examples 'user with non-organizer role' do |role_name|
|
||||||
|
%w(organizer cfp info_desk volunteers_coordinator).each do |role|
|
||||||
|
if role == role_name
|
||||||
|
it{ should be_able_to(:toggle_user, Role.find_by(name: role, resource: my_conference)) }
|
||||||
|
else
|
||||||
|
it{ should_not be_able_to(:toggle_user, Role.find_by(name: role, resource: my_conference)) }
|
||||||
|
end
|
||||||
|
it{ should_not be_able_to(:update, Role.find_by(name: role, resource: my_conference)) }
|
||||||
|
it{ should_not be_able_to(:edit, Role.find_by(name: role, resource: my_conference)) }
|
||||||
|
it{ should be_able_to(:show, Role.find_by(name: role, resource: my_conference)) }
|
||||||
|
it{ should be_able_to(:index, Role.find_by(name: role, resource: my_conference)) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when user has the role organizer' do
|
context 'when user has the role organizer' do
|
||||||
let!(:my_conference) { create(:full_conference) }
|
let!(:my_conference) { create(:full_conference) }
|
||||||
let(:role) { Role.find_by(name: 'organizer', resource: my_conference) }
|
let(:role) { Role.find_by(name: 'organizer', resource: my_conference) }
|
||||||
|
|
@ -190,6 +218,16 @@ describe 'User' do
|
||||||
it{ should_not be_able_to(:manage, other_event.commercials.first) }
|
it{ should_not be_able_to(:manage, other_event.commercials.first) }
|
||||||
it{ should be_able_to(:index, my_event.comment_threads.first) }
|
it{ should be_able_to(:index, my_event.comment_threads.first) }
|
||||||
it{ should_not be_able_to(:index, other_event.comment_threads.first) }
|
it{ should_not be_able_to(:index, other_event.comment_threads.first) }
|
||||||
|
|
||||||
|
%w(organizer cfp info_desk volunteers_coordinator).each do |role|
|
||||||
|
it{ should be_able_to(:toggle_user, Role.find_by(name: role, resource: my_conference)) }
|
||||||
|
it{ should be_able_to(:edit, Role.find_by(name: role, resource: my_conference)) }
|
||||||
|
it{ should be_able_to(:update, Role.find_by(name: role, resource: my_conference)) }
|
||||||
|
it{ should be_able_to(:show, Role.find_by(name: role, resource: my_conference)) }
|
||||||
|
it{ should be_able_to(:index, Role.find_by(name: role, resource: my_conference)) }
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'user with any role'
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when user has the role cfp' do
|
context 'when user has the role cfp' do
|
||||||
|
|
@ -245,6 +283,9 @@ describe 'User' do
|
||||||
it{ should_not be_able_to(:manage, other_event.commercials.first) }
|
it{ should_not be_able_to(:manage, other_event.commercials.first) }
|
||||||
it{ should be_able_to(:index, my_event.comment_threads.first) }
|
it{ should be_able_to(:index, my_event.comment_threads.first) }
|
||||||
it{ should_not be_able_to(:index, other_event.comment_threads.first) }
|
it{ should_not be_able_to(:index, other_event.comment_threads.first) }
|
||||||
|
|
||||||
|
it_behaves_like 'user with any role'
|
||||||
|
it_behaves_like 'user with non-organizer role', 'cfp'
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when user has the role info_desk' do
|
context 'when user has the role info_desk' do
|
||||||
|
|
@ -300,6 +341,9 @@ describe 'User' do
|
||||||
it{ should_not be_able_to(:manage, other_event.commercials.first) }
|
it{ should_not be_able_to(:manage, other_event.commercials.first) }
|
||||||
it{ should_not be_able_to(:index, my_event.comment_threads.first) }
|
it{ should_not be_able_to(:index, my_event.comment_threads.first) }
|
||||||
it{ should_not be_able_to(:index, other_event.comment_threads.first) }
|
it{ should_not be_able_to(:index, other_event.comment_threads.first) }
|
||||||
|
|
||||||
|
it_behaves_like 'user with any role'
|
||||||
|
it_behaves_like 'user with non-organizer role', 'info_desk'
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when user has the role volunteers_coordinator' do
|
context 'when user has the role volunteers_coordinator' do
|
||||||
|
|
@ -357,6 +401,9 @@ describe 'User' do
|
||||||
it{ should_not be_able_to(:index, other_event.comment_threads.first) }
|
it{ should_not be_able_to(:index, other_event.comment_threads.first) }
|
||||||
it 'should be_able to :manage Vposition'
|
it 'should be_able to :manage Vposition'
|
||||||
it 'should be_able to :manage Vday'
|
it 'should be_able to :manage Vday'
|
||||||
|
|
||||||
|
it_behaves_like 'user with any role'
|
||||||
|
it_behaves_like 'user with non-organizer role', 'volunteers_coordinator'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue