Skip to content

Commit

Permalink
Merge pull request #433 from codeforamerica/update-pundit
Browse files Browse the repository at this point in the history
Update Pundit policies and authorizations
  • Loading branch information
monfresh committed Dec 24, 2017
2 parents 24400d3 + b0743ad commit d198bf8
Show file tree
Hide file tree
Showing 35 changed files with 1,377 additions and 73 deletions.
28 changes: 28 additions & 0 deletions .reek
@@ -1,5 +1,33 @@
InstanceVariableAssumption:
exclude:
- Admin::ContactsController
- Admin::LocationsController
- Admin::OrganizationsController
- Admin::OrganizationContactsController
- Admin::ProgramsController
- Admin::ServiceContactsController
- Admin::ServicesController
IrresponsibleModule:
enabled: false
NestedIterators:
exclude:
- Admin::OrganizationsController#index
TooManyMethods:
exclude:
- Admin::CsvController
- Admin::ServicesController
TooManyStatements:
max_statements: 6
exclude:
- Admin::ContactsController
- Admin::OrganizationsController
- Admin::OrganizationContactsController
- Admin::ServiceContactsController
- Admin::ServicesController
UtilityFunction:
exclude:
- Admin::ServicesController#program_ids_for
- Admin::CsvController#zip_file_name
'spec':
DataClump:
enabled: false
Expand Down
1 change: 1 addition & 0 deletions .rubocop.yml
Expand Up @@ -47,6 +47,7 @@ Metrics/ClassLength:
Max: 100
Exclude:
- spec/**/*
- 'app/controllers/admin/services_controller.rb'

Metrics/LineLength:
Description: Limit lines to 80 characters.
Expand Down
10 changes: 9 additions & 1 deletion app/controllers/admin/contacts_controller.rb
Expand Up @@ -14,6 +14,8 @@ def update
@contact = Contact.find(params[:id])
@location = Location.find(params[:location_id])

authorize @location

if @contact.update(contact_params)
flash[:notice] = 'Contact was successfully updated.'
redirect_to [:admin, @location, @contact]
Expand All @@ -34,6 +36,8 @@ def create
@location = Location.find(params[:location_id])
@contact = @location.contacts.new(contact_params)

authorize @location

if @contact.save
flash[:notice] = "Contact '#{@contact.name}' was successfully created."
redirect_to admin_location_path(@location)
Expand All @@ -44,8 +48,12 @@ def create

def destroy
contact = Contact.find(params[:id])
location = contact.location

authorize location

contact.destroy
redirect_to admin_location_path(contact.location),
redirect_to admin_location_path(location),
notice: "Contact '#{contact.name}' was successfully deleted."
end

Expand Down
7 changes: 7 additions & 0 deletions app/controllers/admin/csv_controller.rb
@@ -1,5 +1,7 @@
class Admin
class CsvController < ApplicationController
before_action :authenticate_admin!
before_action :authorize_admin
# The CSV content for each action is defined in
# app/views/admin/csv/{action_name}.csv.shaper

Expand Down Expand Up @@ -45,6 +47,11 @@ def download_zip

private

def authorize_admin
return if current_admin.super_admin?
user_not_authorized
end

def tmp_file_name
@tmp_file_name ||= Rails.root.join('tmp', 'archive.zip')
end
Expand Down
16 changes: 7 additions & 9 deletions app/controllers/admin/locations_controller.rb
Expand Up @@ -19,6 +19,8 @@ def update
@location = Location.find(params[:id])
@org = @location.organization

authorize @location

if @location.update(location_params)
redirect_to [:admin, @location],
notice: 'Location was successfully updated.'
Expand All @@ -34,8 +36,9 @@ def new

def create
@location = Location.new(location_params)
org = @location.organization

assign_location_to_org(policy_scope(Organization))
authorize org if org.present?

if @location.save
redirect_to [:admin, @location], notice: 'Location was successfully created.'
Expand All @@ -46,20 +49,15 @@ def create

def destroy
location = Location.find(params[:id])

authorize location

location.destroy
redirect_to admin_locations_path
end

private

def assign_location_to_org(admin_orgs)
org_id = location_params[:organization_id]

if admin_orgs.select { |org| org[0] == org_id.to_i }.present?
@location.organization = Organization.find(org_id)
end
end

# rubocop:disable MethodLength
def location_params
params.require(:location).permit(
Expand Down
8 changes: 7 additions & 1 deletion app/controllers/admin/organization_contacts_controller.rb
Expand Up @@ -7,13 +7,15 @@ def edit
@organization = Organization.find(params[:organization_id])
@contact = Contact.find(params[:id])

authorize @organization
authorize @contact
end

def update
@contact = Contact.find(params[:id])
@organization = Organization.find(params[:organization_id])

authorize @contact

if @contact.update(contact_params)
flash[:notice] = 'Contact was successfully updated.'
redirect_to [:admin, @organization, @contact]
Expand All @@ -34,6 +36,8 @@ def create
@organization = Organization.find(params[:organization_id])
@contact = @organization.contacts.new(contact_params)

authorize @contact

if @contact.save
flash[:notice] = "Contact '#{@contact.name}' was successfully created."
redirect_to admin_organization_path(@organization)
Expand All @@ -44,6 +48,8 @@ def create

def destroy
contact = Contact.find(params[:id])
authorize contact

contact.destroy
redirect_to admin_organization_path(contact.organization),
notice: "Contact '#{contact.name}' was successfully deleted."
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/admin/organizations_controller.rb
Expand Up @@ -26,6 +26,7 @@ def edit
def update
@organization = Organization.find(params[:id])

authorize @organization
preprocess_organization_params

if @organization.update(org_params)
Expand All @@ -43,8 +44,8 @@ def new

def create
preprocess_organization_params

@organization = Organization.new(org_params)
authorize @organization

if @organization.save
redirect_to admin_organizations_url,
Expand All @@ -56,6 +57,7 @@ def create

def destroy
organization = Organization.find(params[:id])
authorize organization
organization.destroy
redirect_to admin_organizations_path
end
Expand Down
14 changes: 5 additions & 9 deletions app/controllers/admin/programs_controller.rb
Expand Up @@ -17,6 +17,8 @@ def edit
def update
@program = Program.find(params[:id])

authorize @program

if @program.update(program_params)
redirect_to [:admin, @program],
notice: 'Program was successfully updated.'
Expand All @@ -32,8 +34,9 @@ def new

def create
@program = Program.new(program_params)
org = @program.organization

add_org_to_program_if_authorized
authorize @program if org.present?

if @program.save
redirect_to admin_programs_url,
Expand All @@ -45,20 +48,13 @@ def create

def destroy
program = Program.find(params[:id])
authorize program
program.destroy
redirect_to admin_programs_path
end

private

def add_org_to_program_if_authorized
org_id = program_params[:organization_id]

if policy_scope(Organization).select { |org| org[0] == org_id.to_i }.present?
@program.organization_id = org_id
end
end

def program_params
params.require(:program).permit(:alternate_name, :name, :organization_id)
end
Expand Down
17 changes: 14 additions & 3 deletions app/controllers/admin/service_contacts_controller.rb
Expand Up @@ -13,10 +13,13 @@ def edit
def update
@contact = Contact.find(params[:id])
@service = Service.find(params[:service_id])
location = @service.location

authorize location

if @contact.update(contact_params)
flash[:notice] = 'Contact was successfully updated.'
redirect_to [:admin, @service.location, @service, @contact]
redirect_to [:admin, location, @service, @contact]
else
render :edit
end
Expand All @@ -33,9 +36,12 @@ def new
def create
@service = Service.find(params[:service_id])
@contact = @service.contacts.new(contact_params)
location = @service.location

authorize location

if @contact.save
redirect_to admin_location_service_path(@service.location, @service),
redirect_to admin_location_service_path(location, @service),
notice: "Contact '#{@contact.name}' was successfully created."
else
render :new
Expand All @@ -44,8 +50,13 @@ def create

def destroy
contact = Contact.find(params[:id])
service = contact.service
location = service.location

authorize location

contact.destroy
redirect_to admin_location_service_path(contact.service.location, contact.service),
redirect_to admin_location_service_path(location, service),
notice: "Contact '#{contact.name}' was successfully deleted."
end

Expand Down
37 changes: 20 additions & 17 deletions app/controllers/admin/services_controller.rb
Expand Up @@ -18,8 +18,8 @@ def edit

def update
assign_location_service_and_taxonomy_ids

preprocess_service_params
authorize @location
preprocess_service

if @service.update(service_params.except(:locations))
Expand All @@ -39,15 +39,8 @@ def new
@service = Service.new
end

# rubocop:disable Metrics/MethodLength
def create
preprocess_service_params

@location = Location.find(params[:location_id])
@service = @location.services.new(service_params.except(:locations))
@taxonomy_ids = []

preprocess_service
prepare_and_authorize_service_creation

if @service.save
redirect_to admin_location_path(@location),
Expand All @@ -56,25 +49,36 @@ def create
render :new
end
end
# rubocop:enable Metrics/MethodLength

def destroy
service = Service.find(params[:id])
authorize service.location
service.destroy
redirect_to admin_locations_path
end

private

def preprocess_service
add_program_to_service_if_authorized
add_service_to_location_if_authorized
def prepare_and_authorize_service_creation
preprocess_service_params

@location = Location.find(params[:location_id])
@service = @location.services.new(service_params.except(:locations))
@taxonomy_ids = []

authorize @location
preprocess_service
end

def preprocess_service_params
shift_and_split_params(params[:service], :keywords)
end

def preprocess_service
add_program_to_service_if_authorized
add_service_to_location_if_authorized
end

def add_program_to_service_if_authorized
prog_id = service_params[:program_id]
@service.program = nil and return if prog_id.blank?
Expand All @@ -97,10 +101,9 @@ def add_service_to_location_if_authorized
end

def location_ids
return if service_params[:locations].blank?
service_params[:locations].select do |id|
location_ids_for(@service).include?(id.to_i)
end
locations = service_params[:locations]
return if locations.blank?
locations.select { |id| location_ids_for(@service).include?(id.to_i) }
end

def location_ids_for(service)
Expand Down
18 changes: 17 additions & 1 deletion app/policies/application_policy.rb
Expand Up @@ -6,14 +6,30 @@ def initialize(user, record)
@record = record
end

def edit?
def create?
return true if user.super_admin?
scope.flatten.include?(record.id)
end

def scope
Pundit.policy_scope!(user, record.class)
end

alias new? create?
alias edit? create?
alias destroy? create?
alias update? create?

private

def orgs_user_can_access
@orgs_user_can_access ||= Pundit.policy_scope!(user, Organization)
end

def can_access_at_least_one_organization?
orgs_user_can_access.present?
end

class Scope
attr_reader :user, :scope

Expand Down

0 comments on commit d198bf8

Please sign in to comment.