Files
osem/app/models/admin_ability.rb
AEtherC0r3 7eea930269 Implement track scheduling
Add track association to schedule
Show schedules in admin sidebar to track organizers
Allow track organizers to manage the schedules of their tracks
Don't allow self-organized track events to be dragged or unscheduled in
a conference schedule
Make scheduled events of self-organized tracks appear semitransparent in
conference schedules
Make the rooms of confirmed self_organized tracks appear semitransparent
and don't allow events to be scheduled to it in the conference schedules
during the dates of its track
Create admin/SchedulesController#new action
Add a button in admin/Schedules#index to create schedules for tracks
Add self_organized scope to Track
Modify Schedules#show to handle track schedules and show a unified
schedule
Allow track organizers to create new schedules for their tracks
Correctly identify scheduled and unscheduled events in Schedules#events
Fix Event#room and Event#time for when the event is scheduled in a track
schedule
Modify Program#selected_event_schedules to include the event_schedules
of selected track schedules
Modify Track#revoke_role_and_cleanup to destroy the track's schedules
and revert its events' state to new
Add tabs for conference and track schedules in admin/Schedules#index
Add button to Create/Show a tracks schedule in Tracks#index and #show
Fix concurrent_events in application_helper because of changes in
Program#selected_event_schedules
Do not take into account cfp_active in Event#valid_track
Modify EventsController#get_tracks accordingly
Enforce cfp_active of track to be enabled for proposals in
ProposalsController#create and #update
Add support for multiple schedules per track
Add selected_schedule_id to Track
Load EventSchedules of selected track schedules for conference schedules
in admin/SchedulesController#show
Modify SchedulesController#show to take into account only the selected
track schedules
Create Event#selected_schedule_id and use it in Event#scheduled? and
Event#time
Validate that an EventSchedule for an event of a self-organized track
belongs to one of the track's schedules
Add 'Manage' button in Tracks#index, #show that sends you to the admin
side of things
Add admin/TracksController#update_selected_schedule to update the
selected_schedule_id of tracks
2017-08-26 00:31:44 +03:00

325 lines
15 KiB
Ruby

class AdminAbility
include CanCan::Ability
def initialize(user)
# Order Abilities
# (Check https://github.com/CanCanCommunity/cancancan/wiki/Ability-Precedence)
# Check roles of user, using rolify. Role name is *case sensitive*
# user.is_organizer? or user.has_role? :organizer
# user.is_cfp_of? Conference or user.has_role? :cfp, Conference
# user.is_info_desk_of? Conference
# user.is_volunteers_coordinator_of? Conference
# user.is_attendee_of? 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 ||= User.new
signed_in_with_roles(user)
end
def common_abilities_for_roles(user)
can :manage, Registration, user_id: user.id
can :index, Conference
can :show, Registration, &:new_record?
can [:new, :create], Registration do |registration|
conference = registration.conference
conference.registration_open? && !conference.registration_limit_exceeded? || conference.program.speakers.confirmed.include?(user)
end
can [:index, :admins], Organization
can :index, Ticket
can :manage, TicketPurchase, user_id: user.id
can [:new, :create], Payment, user_id: user.id
can [:create, :destroy], Subscription, user_id: user.id
can [:new, :create], Event do |event|
event.program.cfp_open? && event.new_record?
end
# can manage the commercials of their own events
can :manage, Commercial, commercialable_type: 'Event', commercialable_id: user.events.pluck(:id)
can [:destroy], Openid
can :access, Admin
can :index, Commercial, commercialable_type: 'Conference'
cannot [:edit, :update, :destroy], Question, global: true
# for admins
can :manage, :all if user.is_admin
# even admin cannot create new users with ICHAIN enabled
cannot [:new, :create], User if ENV['OSEM_ICHAIN_ENABLED'] == 'true'
cannot :revert_object, PaperTrail::Version do |version|
(version.event == 'create' && %w[Conference User Event].include?(version.item_type))
end
cannot :revert_attribute, PaperTrail::Version do |version|
version.event != 'update' || version.item.nil?
end
# Can't create cfp if there are no available cfp types
cannot [:new, :create], Cfp do |cfp|
cfp.program.remaining_cfp_types.empty?
end
cannot :destroy, Program
# Do not delete venue, when there are rooms being used
cannot :destroy, Venue do |venue|
venue.conference.program.events.where.not(room_id: nil).any?
end
# Prevent requests for tracks from being destroyed
cannot :destroy, Track do |track|
track.self_organized?
end
# Can't accept a booth when booth_limit is reached
cannot :accept, Booth do |booth|
conference = booth.conference
conference.maximum_accepted_booths?
end
end
# Abilities for signed in users with roles
def signed_in_with_roles(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
signed_in_with_volunteers_coordinator_role(user) if user.has_role? :volunteers_coordinator, :any
signed_in_with_track_organizer_role(user) if user.has_role? :track_organizer, :any
common_abilities_for_roles(user)
end
def signed_in_with_organization_admin_role(user)
org_ids_for_organization_admin = Organization.with_role(:organization_admin, user).pluck(:id)
conf_ids_for_organization_admin = Conference.where(organization_id: org_ids_for_organization_admin).pluck(:id)
can [:read, :update, :destroy, :assign_org_admins, :unassign_org_admins, :admins], Organization, id: org_ids_for_organization_admin
can :new, Conference
can :manage, Conference, organization_id: org_ids_for_organization_admin
can [:index, :show], Role
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 = conf_ids_for_organization_admin.concat(Conference.with_role(:organizer, user).pluck(:id)).uniq
# ids of all the tracks that belong to the programs of the above conferences
track_ids = Track.joins(:program).where('programs.conference_id IN (?)', conf_ids).pluck(:id)
can :manage, Resource, conference_id: conf_ids
can [:read, :update, :destroy], Conference, id: conf_ids
can :manage, Splashpage, conference_id: conf_ids
can :manage, Contact, conference_id: conf_ids
can :manage, EmailSettings, conference_id: conf_ids
can :manage, Campaign, conference_id: conf_ids
can :manage, Target, conference_id: conf_ids
can :manage, Commercial, commercialable_type: 'Conference',
commercialable_id: conf_ids
can :manage, Registration, conference_id: conf_ids
can :manage, RegistrationPeriod do |registration_period|
conference = registration_period.conference
conf_ids.include?(conference.id) && conference.tickets.for_registration.any?
end
can :manage, Booth, conference_id: conf_ids
can :manage, Question, conference_id: conf_ids
can :manage, Question do |question|
!(question.conferences.pluck(:id) & conf_ids).empty?
end
can :manage, Vposition, conference_id: conf_ids
can :manage, Vday, conference_id: conf_ids
can :manage, Program, conference_id: conf_ids
can :manage, Schedule, program: { conference_id: conf_ids }
can :manage, EventSchedule, schedule: { program: { conference_id: conf_ids } }
can :manage, Cfp, program: { conference_id: conf_ids }
can :manage, Event, program: { conference_id: conf_ids }
can :manage, EventType, program: { conference_id: conf_ids }
can :manage, Track, program: { conference_id: conf_ids }
can :manage, DifficultyLevel, program: { conference_id: conf_ids }
can :manage, Commercial, commercialable_type: 'Event',
commercialable_id: Event.where(program_id: Program.where(conference_id: conf_ids).pluck(:id)).pluck(:id)
can :manage, Venue, conference_id: conf_ids
can :manage, Commercial, commercialable_type: 'Venue',
commercialable_id: Venue.where(conference_id: conf_ids).pluck(:id)
can :manage, Lodging, conference_id: conf_ids
can :manage, Room, venue: { conference_id: conf_ids }
can :manage, Sponsor, conference_id: conf_ids
can :manage, SponsorshipLevel, conference_id: conf_ids
can :manage, Ticket, conference_id: conf_ids
can :create, TicketScanning do |ticket_scanning|
conf_id = ticket_scanning.physical_ticket.ticket_purchase.conference_id
conf_ids.include? conf_id
end
can :index, Comment, commentable_type: 'Event',
commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids).pluck(:id)).pluck(:id)
# Abilities for Role (Conference resource)
can [:index, :show], Role do |role|
role.resource_type == 'Conference' || role.resource_type == 'Track'
end
can [:edit, :update, :toggle_user], Role do |role|
role.resource_type == 'Conference' && (conf_ids.include? role.resource_id) ||
role.resource_type == 'Track' && (track_ids.include? role.resource_id)
end
can [:index, :revert_object, :revert_attribute], PaperTrail::Version, item_type: 'User'
can [:index, :revert_object, :revert_attribute], PaperTrail::Version, conference_id: conf_ids
end
def signed_in_with_cfp_role(user)
# ids of all the conferences for which the user has the 'cfp' role
conf_ids_for_cfp = Conference.with_role(:cfp, user).pluck(:id)
can :show, Conference do |conf|
conf_ids_for_cfp.include?(conf.id)
end
can [:index, :show, :update], Resource, conference_id: conf_ids_for_cfp
can :manage, Booth, 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, Track, program: { conference_id: conf_ids_for_cfp }
can :manage, DifficultyLevel, program: { conference_id: conf_ids_for_cfp }
can :manage, EmailSettings, conference_id: conf_ids_for_cfp
can :manage, Schedule, program: { conference_id: conf_ids_for_cfp }
can :manage, Room, venue: { conference_id: conf_ids_for_cfp }
can :show, Venue, conference_id: conf_ids_for_cfp
can :show, Commercial, commercialable_type: 'Venue', commercialable_id: Venue.where(conference_id: conf_ids_for_cfp).pluck(:id)
can :manage, Cfp, program: { conference_id: conf_ids_for_cfp }
can :manage, Program, conference_id: conf_ids_for_cfp
can :manage, Commercial, commercialable_type: 'Event',
commercialable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_cfp).pluck(:id)).pluck(:id)
can :index, Comment, commentable_type: 'Event',
commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_cfp).pluck(:id)).pluck(:id)
# Abilities for Role (Conference resource)
can [:index, :show], Role do |role|
role.resource_type == 'Conference' || role.resource_type == 'Track'
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' && role.name == 'cfp' &&
(Conference.with_role(:cfp, user).pluck(:id).include? role.resource_id)
end
can [:index, :revert_object, :revert_attribute], PaperTrail::Version,
item_type: %w[Event EventType Track DifficultyLevel EmailSettings Room Cfp Program Comment], conference_id: conf_ids_for_cfp
can [:index, :revert_object, :revert_attribute], PaperTrail::Version,
["item_type = 'Commercial' AND conference_id IN (?) AND (object LIKE '%Event%' OR object_changes LIKE '%Event%')", conf_ids_for_cfp] do |version|
version.item_type == 'Commercial' && conf_ids_for_cfp.include?(version.conference_id) &&
(version.object.to_s.include?('Event') || version.object_changes.to_s.include?('Event'))
end
end
def signed_in_with_info_desk_role(user)
# ids of all the conferences for which the user has the 'info_desk' role
conf_ids_for_info_desk = Conference.with_role(:info_desk, user).pluck(:id)
can :show, Conference do |conf|
conf_ids_for_info_desk.include?(conf.id)
end
can [:index, :show, :update], Resource, 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 do |question|
!(question.conferences.pluck(:id) & conf_ids_for_info_desk).empty?
end
can :create, TicketScanning do |ticket_scanning|
conf_id = ticket_scanning.physical_ticket.ticket_purchase.conference_id
conf_ids_for_info_desk.include? conf_id
end
# Abilities for Role (Conference resource)
can [:index, :show], Role do |role|
role.resource_type == 'Conference' || role.resource_type == 'Track'
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' && role.name == 'info_desk' &&
(Conference.with_role(:info_desk, user).pluck(:id).include? role.resource_id)
end
can [:index, :revert_object, :revert_attribute], PaperTrail::Version, item_type: 'Registration', conference_id: conf_ids_for_info_desk
end
def signed_in_with_volunteers_coordinator_role(user)
# ids of all the conferences for which the user has the 'volunteers_coordinator' role
conf_ids_for_volunteers_coordinator = Conference.with_role(:volunteers_coordinator, user).pluck(:id)
can :show, Conference do |conf|
conf_ids_for_volunteers_coordinator.include?(conf.id)
end
can [:index, :show, :update], Resource, 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
# Abilities for Role (Conference resource)
can [:index, :show], Role do |role|
role.resource_type == 'Conference' || role.resource_type == 'Track'
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' && role.name == 'volunteers_coordinator' &&
(Conference.with_role(:volunteers_coordinator, user).pluck(:id).include? role.resource_id)
end
end
def signed_in_with_track_organizer_role(user)
# ids of all the conferences for which the user has the 'track organizer' role
conf_ids_for_track_organizer = Track.with_role(:track_organizer, user).joins(:program).pluck(:conference_id)
# ids of all the tracks for which the user has the 'track_organizer' role
track_ids_for_track_organizer = Track.with_role(:track_organizer, user).pluck(:id)
can :show, Conference do |conf|
conf_ids_for_track_organizer.include?(conf.id)
end
# Show Program in the admin sidebar
can :show, Program, conference_id: conf_ids_for_track_organizer
# Show Tracks in the admin sidebar
can :update, Track do |track|
track.new_record? && conf_ids_for_track_organizer.include?(track.program.conference_id)
end
can :manage, Track, id: track_ids_for_track_organizer
cannot [:edit, :update], Track do |track|
track.self_organized_and_accepted_or_confirmed?
end
# Show Roles in the admin sidebar and allow authorization of the index action
can [:index, :show], Role do |role|
role.resource_type == 'Conference' || role.resource_type == 'Track'
end
can :toggle_user, Role do |role|
role.resource_type == 'Track' && track_ids_for_track_organizer.include?(role.resource_id)
end
# Show Events in the admin sidebar
can :update, Event do |event|
event.new_record? && conf_ids_for_track_organizer.include?(event.program.conference_id)
end
can :manage, Event, track_id: track_ids_for_track_organizer
can :manage, Commercial, commercialable_type: 'Event',
commercialable_id: Event.where(track_id: track_ids_for_track_organizer).pluck(:id)
# Show Scheduless in the admin sidebar
can :update, Schedule do |schedule|
schedule.new_record? && conf_ids_for_track_organizer.include?(schedule.program.conference_id)
end
# Show new track schedule button
can :new, Schedule do |schedule|
schedule.new_record? && conf_ids_for_track_organizer.include?(schedule.program.conference_id) && schedule.track.try(:new_record?)
end
can :manage, Schedule, track_id: track_ids_for_track_organizer
can :manage, EventSchedule, schedule: { track_id: track_ids_for_track_organizer }
end
end