Introduce organization admins

This commit is contained in:
shlok007 2017-06-13 04:39:47 +05:30
parent f37d3095e1
commit b72e64b238
6 changed files with 96 additions and 41 deletions

View file

@ -8,7 +8,7 @@ module Admin
return false
end
unless (current_user.has_role? :organizer, :any) || (current_user.has_role? :cfp, :any) ||
(current_user.has_role? :info_desk, :any) ||
(current_user.has_role? :info_desk, :any) || (current_user.has_role? :organization_admin, :any) ||
(current_user.has_role? :volunteers_coordinator, :any) || current_user.is_admin
raise CanCan::AccessDenied.new('You are not authorized to access this area!')
end

View file

@ -1,6 +1,7 @@
module Admin
class OrganizationsController < Admin::BaseController
load_and_authorize_resource :organization
after_action :assign_role, only: :create
def index
@organizations = Organization.all
@ -45,6 +46,10 @@ module Admin
private
def assign_role
current_user.add_role :organization_admin, @organization
end
def organization_params
params.require(:organization).permit(:name, :description, :picture)
end

View file

@ -110,6 +110,7 @@ class Ability
# Abilities from not_signed_in and signed_in are also inherited
signed_in(user)
signed_in_with_organization_admin_role(user) if user.has_role? :organization_admin, :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_info_desk_role(user) if user.has_role? :info_desk, :any
@ -146,57 +147,73 @@ class Ability
end
end
def signed_in_with_organizer_role(user)
# ids of all the conferences for which the user has the 'organizer' role
conf_ids_for_organizer = Conference.with_role(:organizer, user).pluck(:id)
def signed_in_with_organization_admin_role(user)
org_ids_for_organization_admin = Organization.with_role(:organization_admin, user).pluck(:id)
can :manage, Resource, conference_id: conf_ids_for_organizer
can [:new, :create], Conference if user.has_role?(:organizer, :any)
can :manage, Conference, id: conf_ids_for_organizer
can :manage, Splashpage, conference_id: conf_ids_for_organizer
can :manage, Contact, conference_id: conf_ids_for_organizer
can :manage, EmailSettings, conference_id: conf_ids_for_organizer
can :manage, Campaign, conference_id: conf_ids_for_organizer
can :manage, Target, conference_id: conf_ids_for_organizer
can :manage, Commercial, commercialable_type: 'Conference',
commercialable_id: conf_ids_for_organizer
can :manage, Registration, conference_id: conf_ids_for_organizer
can :manage, RegistrationPeriod, conference_id: conf_ids_for_organizer
can :manage, Question, conference_id: conf_ids_for_organizer
can :manage, Question do |question|
!(question.conferences.pluck(:id) & conf_ids_for_organizer).empty?
can :manage, Organization, id: org_ids_for_organization_admin
can :manage, Conference, organization_id: org_ids_for_organization_admin
conf_ids_for_organization_admin = []
org_ids_for_organization_admin.each do |org_id|
conf_ids_for_organization_admin += Organization.find(org_id).conferences.pluck(:id)
end
can :manage, Vposition, conference_id: conf_ids_for_organizer
can :manage, Vday, conference_id: conf_ids_for_organizer
can :manage, Program, conference_id: conf_ids_for_organizer
can :manage, Schedule, program: { conference_id: conf_ids_for_organizer }
can :manage, EventSchedule, schedule: { program: { conference_id: conf_ids_for_organizer } }
can :manage, Cfp, program: { conference_id: conf_ids_for_organizer }
can :manage, Event, program: { conference_id: conf_ids_for_organizer}
can :manage, EventType, program: { conference_id: conf_ids_for_organizer}
can :manage, Track, program: { conference_id: conf_ids_for_organizer}
can :manage, DifficultyLevel, program: { conference_id: conf_ids_for_organizer}
can [:index, :show], Role
can [:edit, :update], Role do |role|
role.resource_type == 'Organization' && (org_ids_for_organization_admin.include? role.resource_id)
end
signed_in_with_organizer_role(user, conf_ids_for_organization_admin)
end
def signed_in_with_organizer_role(user, conf_ids_for_organization_admin = [])
# ids of all the conferences for which the user has the 'organizer' role and
# conferences that belong to organizations for which user is 'organization_admin'
conf_ids_for_organization_admin_and_organizer = conf_ids_for_organization_admin.concat(Conference.with_role(:organizer, user).pluck(:id)).uniq
can :manage, Resource, conference_id: conf_ids_for_organization_admin_and_organizer
can [:new, :create], Conference if user.has_role?(:organizer, :any)
can :manage, Conference, id: conf_ids_for_organization_admin_and_organizer
can :manage, Splashpage, conference_id: conf_ids_for_organization_admin_and_organizer
can :manage, Contact, conference_id: conf_ids_for_organization_admin_and_organizer
can :manage, EmailSettings, conference_id: conf_ids_for_organization_admin_and_organizer
can :manage, Campaign, conference_id: conf_ids_for_organization_admin_and_organizer
can :manage, Target, conference_id: conf_ids_for_organization_admin_and_organizer
can :manage, Commercial, commercialable_type: 'Conference',
commercialable_id: conf_ids_for_organization_admin_and_organizer
can :manage, Registration, conference_id: conf_ids_for_organization_admin_and_organizer
can :manage, RegistrationPeriod, conference_id: conf_ids_for_organization_admin_and_organizer
can :manage, Question, conference_id: conf_ids_for_organization_admin_and_organizer
can :manage, Question do |question|
!(question.conferences.pluck(:id) & conf_ids_for_organization_admin_and_organizer).empty?
end
can :manage, Vposition, conference_id: conf_ids_for_organization_admin_and_organizer
can :manage, Vday, conference_id: conf_ids_for_organization_admin_and_organizer
can :manage, Program, conference_id: conf_ids_for_organization_admin_and_organizer
can :manage, Schedule, program: { conference_id: conf_ids_for_organization_admin_and_organizer }
can :manage, EventSchedule, schedule: { program: { conference_id: conf_ids_for_organization_admin_and_organizer } }
can :manage, Cfp, program: { conference_id: conf_ids_for_organization_admin_and_organizer}
can :manage, Event, program: { conference_id: conf_ids_for_organization_admin_and_organizer}
can :manage, EventType, program: { conference_id: conf_ids_for_organization_admin_and_organizer}
can :manage, Track, program: { conference_id: conf_ids_for_organization_admin_and_organizer}
can :manage, DifficultyLevel, program: { conference_id: conf_ids_for_organization_admin_and_organizer}
can :manage, Commercial, commercialable_type: 'Event',
commercialable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_organizer).pluck(:id)).pluck(:id)
can :manage, Venue, conference_id: conf_ids_for_organizer
commercialable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_organization_admin_and_organizer).pluck(:id)).pluck(:id)
can :manage, Venue, conference_id: conf_ids_for_organization_admin_and_organizer
can :manage, Commercial, commercialable_type: 'Venue',
commercialable_id: Venue.where(conference_id: conf_ids_for_organizer).pluck(:id)
can :manage, Lodging, conference_id: conf_ids_for_organizer
can :manage, Room, venue: { conference_id: conf_ids_for_organizer}
can :manage, Sponsor, conference_id: conf_ids_for_organizer
can :manage, SponsorshipLevel, conference_id: conf_ids_for_organizer
can :manage, Ticket, conference_id: conf_ids_for_organizer
commercialable_id: Venue.where(conference_id: conf_ids_for_organization_admin_and_organizer).pluck(:id)
can :manage, Lodging, conference_id: conf_ids_for_organization_admin_and_organizer
can :manage, Room, venue: { conference_id: conf_ids_for_organization_admin_and_organizer}
can :manage, Sponsor, conference_id: conf_ids_for_organization_admin_and_organizer
can :manage, SponsorshipLevel, conference_id: conf_ids_for_organization_admin_and_organizer
can :manage, Ticket, conference_id: conf_ids_for_organization_admin_and_organizer
can :index, Comment, commentable_type: 'Event',
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_organization_admin_and_organizer).pluck(:id)).pluck(:id)
# Abilities for Role (Conference resource)
can [:index, :show], 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_organization_admin_and_organizer.include? role.resource_id)
end
can [:index, :revert_object, :revert_attribute], PaperTrail::Version do |version|
version.item_type == 'User' || (conf_ids_for_organizer.include? version.conference_id)
version.item_type == 'User' || (conf_ids_for_organization_admin_and_organizer.include? version.conference_id)
end
end

View file

@ -1,7 +1,17 @@
class Organization < ActiveRecord::Base
resourcify :roles, dependent: :delete_all
has_many :conferences, dependent: :destroy
after_create :create_roles
validates :name, presence: true
mount_uploader :picture, PictureUploader, mount_on: :picture
private
def create_roles
Role.where(name: 'organization_admin', resource: self).first_or_create(description: "For the administrators of an organization (who shall have full access to the organization and it's conferences)")
end
end

View file

@ -2,6 +2,10 @@ namespace :roles do
desc 'Adds back deleted roles to all conferences'
task add: :environment do
Organization.all.each do |org|
Role.where(name: 'organization_admin', resource: org).first_or_create(description: "For the administrators of an organization (who shall have full access to the organization and it's conferences)")
end
Conference.all.each do |c|
Role.where(name: 'organizer', resource: c).first_or_create(description: 'For the organizers of the conference (who shall have full access)')
Role.where(name: 'cfp', resource: c).first_or_create(description: 'For the members of the CfP team')

View file

@ -9,7 +9,8 @@ describe 'User' do
subject(:ability){ Ability.new(user) }
let(:user){ nil }
let!(:my_conference) { create(:full_conference) }
let!(:organization) { create(:organization) }
let!(:my_conference) { create(:full_conference, organization: organization) }
let(:my_venue) { my_conference.venue || create(:venue, conference: my_conference) }
let(:my_registration) { create(:registration, conference: my_conference, user: admin) }
@ -44,6 +45,7 @@ describe 'User' do
let!(:other_event_schedule) { create(:event_schedule, schedule: other_schedule) }
# Test abilities for not signed in users
context 'when user is not signed in' do
it{ should be_able_to(:index, Organization)}
it{ should be_able_to(:index, Conference)}
it{ should be_able_to(:show, conference_public)}
@ -138,9 +140,14 @@ describe 'User' do
shared_examples 'user with any role' do
before do
@other_organization = create(:organization)
@other_conference = create(:conference)
end
it{ should_not be_able_to(:update, Role.find_by(name: 'organization_admin', resource: @other_organization)) }
it{ should_not be_able_to(:edit, Role.find_by(name: 'organization_admin', resource: @other_organization)) }
it{ should_not be_able_to(:show, Role.find_by(name: 'organization_admin', resource: @other_organization)) }
%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)) }
@ -164,6 +171,18 @@ describe 'User' do
end
end
context 'when user has the role organization_admin' do
let(:role) { Role.find_by(name: 'organization_admin', resource: organization) }
let(:user) { create(:user, role_ids: [role.id]) }
let(:other_conference) { create(:conference) }
it{ should_not be_able_to(:manage, other_conference) }
it{ should be_able_to(:manage, my_conference) }
it{ should be_able_to(:manage, organization) }
it_behaves_like 'user with any role'
end
context 'when user has the role organizer' do
let(:role) { Role.find_by(name: 'organizer', resource: my_conference) }
let(:user) { create(:user, role_ids: [role.id]) }