question policies

This commit is contained in:
Mark Moser 2016-09-20 18:17:27 -05:00
parent 13610edcd1
commit 8ad98215c1
6 changed files with 119 additions and 12 deletions

View File

@ -2,16 +2,20 @@
module Admin module Admin
class QuestionController < AdminController class QuestionController < AdminController
def index def index
@questions = Question.includes(:quiz).order("quizzes.name", { active: :desc }, :sort) @questions = policy_scope Question.includes(:quiz).order("quizzes.name", { active: :desc }, :sort)
end end
def new def new
authorize Question
@question = Question.new(active: true) @question = Question.new(active: true)
@quizzes = Quiz.all @quizzes = policy_scope Quiz.all
end end
def create def create
@quizzes = Quiz.all authorize Quiz
@quizzes = policy_scope Quiz.all
@question = Question.create(process_question_params) @question = Question.create(process_question_params)
if @question.persisted? if @question.persisted?
@ -24,16 +28,20 @@ module Admin
def view def view
@question = Question.includes(:quiz).find(params[:question_id]) @question = Question.includes(:quiz).find(params[:question_id])
authorize @question
end end
def edit def edit
@quizzes = Quiz.all @quizzes = policy_scope Quiz.all
@question = Question.includes(:quiz).find(params[:question_id]) @question = Question.includes(:quiz).find(params[:question_id])
authorize @question
end end
def update def update
@quizzes = Quiz.all @quizzes = policy_scope Quiz.all
@question = Question.find(params[:question_id]) @question = Question.find(params[:question_id])
authorize @question
if @question.update_attributes(process_question_params) if @question.update_attributes(process_question_params)
redirect_to admin_question_path(@question.to_i), redirect_to admin_question_path(@question.to_i),
@ -46,6 +54,7 @@ module Admin
def options def options
@question = params[:question_id].present? ? Question.find(params[:question_id]) : Question.new @question = params[:question_id].present? ? Question.find(params[:question_id]) : Question.new
authorize @question
render layout: false render layout: false
end end

View File

@ -6,8 +6,8 @@ module Admin
end end
def new def new
authorize Quiz
@quiz = Quiz.new @quiz = Quiz.new
authorize @quiz
end end
def create def create

View File

@ -0,0 +1,38 @@
# frozen_string_literal: true
class QuestionPolicy < ApplicationPolicy
# Question Access Policy
#
# Only Admins and Managers can create or update a quiz (and its questions)
# Reviewers can view any quiz they are linked to
# Recruiters can NOT list or view questions
def view?
return false if user.recruiter?
return true if user.admin? || user.manager?
user.quizzes.include? record.quiz
end
def create?
user.manager? || user.admin?
end
def update?
user.manager? || user.admin?
end
def options?
!user.recruiter?
end
class Scope < Scope
def resolve
raise(Pundit::NotAuthorizedError, 'No Access to resource.') if user.recruiter?
if user.admin? || user.manager?
scope
else
scope.where(quiz_id: user.quizzes.map(&:id))
end
end
end
end

View File

@ -111,3 +111,13 @@ fed10:
- "wibbly wobbly, timey wimey" - "wibbly wobbly, timey wimey"
sort: 9 sort: 9
active: true active: true
admin1:
quiz: admin
question: 'You have a question you want to ask.'
category: Admin
input_type: text
input_options:
sort: 0
active: true

View File

@ -0,0 +1,50 @@
# frozen_string_literal: true
require 'test_helper'
class QuestionPolicyTest < PolicyAssertions::Test
test 'should require current_user' do
assert_raise Pundit::NotAuthorizedError do
QuestionPolicy.new(nil, Question.first).view?
end
end
test 'should allow admin to scope' do
scope = QuestionPolicy::Scope.new(users(:admin), Question).resolve
assert_equal Question.count, scope.count
end
test 'should allow manager to scope' do
scope = QuestionPolicy::Scope.new(users(:manager), Question).resolve
assert_equal Question.count, scope.count
end
test 'should allow reviewer to scope' do
quiz_ids = users(:reviewer).quizzes.map(&:id)
scope = QuestionPolicy::Scope.new(users(:reviewer), Question).resolve
assert_equal Question.where(quiz_id: quiz_ids).count, scope.count
end
test 'should NOT allow recruiter to scope' do
assert_raise Pundit::NotAuthorizedError do
QuestionPolicy::Scope.new(users(:recruiter), Question).resolve
end
end
def test_view
assert_permit users(:admin), questions(:fed1)
assert_permit users(:manager), questions(:fed1)
assert_permit users(:reviewer), questions(:fed1)
refute_permit users(:reviewer), questions(:admin1)
refute_permit users(:recruiter), questions(:fed1)
end
def test_create_and_update
assert_permit users(:admin), Question
assert_permit users(:manager), Question
refute_permit users(:recruiter), Question
refute_permit users(:reviewer), Question
end
end

View File

@ -2,6 +2,12 @@
require 'test_helper' require 'test_helper'
class UserPolicyTest < PolicyAssertions::Test class UserPolicyTest < PolicyAssertions::Test
test 'should require current_user' do
assert_raise Pundit::NotAuthorizedError do
UserPolicy.new(nil, User.first).view?
end
end
test 'should allow admin to scope' do test 'should allow admin to scope' do
scope = UserPolicy::Scope.new(users(:admin), User).resolve scope = UserPolicy::Scope.new(users(:admin), User).resolve
assert_equal User.count, scope.count assert_equal User.count, scope.count
@ -13,12 +19,6 @@ class UserPolicyTest < PolicyAssertions::Test
end end
end end
test 'should require current_user' do
assert_raise Pundit::NotAuthorizedError do
UserPolicy.new(nil, User.first).view?
end
end
def test_view def test_view
assert_permit users(:admin), User.first assert_permit users(:admin), User.first