From 13610edcd14c819b2000b306ea74285645ec1267 Mon Sep 17 00:00:00 2001 From: Mark Moser Date: Tue, 20 Sep 2016 17:19:11 -0500 Subject: [PATCH] quiz policies --- app/controllers/admin/quiz_controller.rb | 7 +++- app/models/user.rb | 18 ++++++++- app/policies/quiz_policy.rb | 31 ++++++++++++++++ app/policies/user_policy.rb | 4 ++ test/fixtures/quizzes.yml | 5 +++ test/policies/quiz_policy_test.rb | 47 ++++++++++++++++++++++++ test/policies/user_policy_test.rb | 10 ++++- 7 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 app/policies/quiz_policy.rb create mode 100644 test/policies/quiz_policy_test.rb diff --git a/app/controllers/admin/quiz_controller.rb b/app/controllers/admin/quiz_controller.rb index 758516f..4ca5fbb 100644 --- a/app/controllers/admin/quiz_controller.rb +++ b/app/controllers/admin/quiz_controller.rb @@ -2,14 +2,16 @@ module Admin class QuizController < AdminController def index - @quizzes = Quiz.all + @quizzes = policy_scope Quiz.all end def new @quiz = Quiz.new + authorize @quiz end def create + authorize Quiz @quiz = Quiz.create(quiz_params) if @quiz.persisted? @@ -22,14 +24,17 @@ module Admin def view @quiz = Quiz.find(params[:quiz_id]) + authorize @quiz end def edit @quiz = Quiz.find(params[:quiz_id]) + authorize @quiz end def update @quiz = Quiz.find(params[:quiz_id]) + authorize @quiz if @quiz.update_attributes(quiz_params) redirect_to admin_quiz_path(@quiz.to_i), diff --git a/app/models/user.rb b/app/models/user.rb index ec706e5..c20f17e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -16,9 +16,23 @@ class User < ApplicationRecord end # TODO: move to mixin: UserRoles - # define remaining helpers def admin? - role == 'admin' + 'admin' == role + end + + # TODO: move to mixin: UserRoles + def manager? + %w(admin manager).include? role + end + + # TODO: move to mixin: UserRoles + def recruiter? + 'recruiter' == role + end + + # TODO: move to mixin: UserRoles + def reviewer? + 'reviewer' == role end private diff --git a/app/policies/quiz_policy.rb b/app/policies/quiz_policy.rb new file mode 100644 index 0000000..49505e8 --- /dev/null +++ b/app/policies/quiz_policy.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true +class QuizPolicy < ApplicationPolicy + # Quiz 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 only list quiz names (for candidate assignments) + + def view? + return true if user.admin? || user.manager? + user.quizzes.include? record + end + + def create? + user.manager? || user.admin? + end + + def update? + user.manager? || user.admin? + end + + class Scope < Scope + def resolve + if user.reviewer? + scope.joins(:reviewers).where('reviewer_to_quizzes.user_id = ?', user.id) + else + scope + end + end + end +end diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index ef5c64a..61be4d4 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -1,5 +1,9 @@ # frozen_string_literal: true class UserPolicy < ApplicationPolicy + # User Access Policy + # + # Only Admins can view, create, or update, users + def view? user.admin? && show? end diff --git a/test/fixtures/quizzes.yml b/test/fixtures/quizzes.yml index daf1e5d..f4bd5fa 100644 --- a/test/fixtures/quizzes.yml +++ b/test/fixtures/quizzes.yml @@ -4,3 +4,8 @@ fed: name: PDR Standard FED Screening unit: PDR dept: FED + +admin: + name: An extra quiz not assigned to anyone + unit: PDR + dept: NOPE diff --git a/test/policies/quiz_policy_test.rb b/test/policies/quiz_policy_test.rb new file mode 100644 index 0000000..e5eb7be --- /dev/null +++ b/test/policies/quiz_policy_test.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true +require 'test_helper' + +class QuizPolicyTest < PolicyAssertions::Test + test 'should require current_user' do + assert_raise Pundit::NotAuthorizedError do + QuizPolicy.new(nil, Quiz.first).view? + end + end + + test 'should allow admin to scope' do + scope = QuizPolicy::Scope.new(users(:admin), Quiz).resolve + assert_equal Quiz.count, scope.count + end + + test 'should allow manager to scope' do + scope = QuizPolicy::Scope.new(users(:manager), Quiz).resolve + assert_equal Quiz.count, scope.count + end + + test 'should allow reviewer to scope' do + scope = QuizPolicy::Scope.new(users(:reviewer), Quiz).resolve + assert_equal users(:reviewer).quizzes.count, scope.count + end + + test 'should allow recruiter to scope' do + scope = QuizPolicy::Scope.new(users(:recruiter), Quiz).resolve + assert_equal Quiz.count, scope.count + end + + def test_view + assert_permit users(:admin), quizzes(:fed) + assert_permit users(:manager), quizzes(:fed) + assert_permit users(:reviewer), quizzes(:fed) + + refute_permit users(:reviewer), quizzes(:admin) + refute_permit users(:recruiter), quizzes(:fed) + end + + def test_create_and_update + assert_permit users(:admin), Quiz + assert_permit users(:manager), Quiz + + refute_permit users(:recruiter), Quiz + refute_permit users(:reviewer), Quiz + end +end diff --git a/test/policies/user_policy_test.rb b/test/policies/user_policy_test.rb index 88d3413..4a9096c 100644 --- a/test/policies/user_policy_test.rb +++ b/test/policies/user_policy_test.rb @@ -20,12 +20,18 @@ class UserPolicyTest < PolicyAssertions::Test end def test_view - refute_permit users(:manager), User.first assert_permit users(:admin), User.first + + refute_permit users(:manager), User.first + refute_permit users(:reviewer), User.first + refute_permit users(:recruiter), User.first end def test_create_and_update - refute_permit users(:manager), User assert_permit users(:admin), User + + refute_permit users(:manager), User + refute_permit users(:reviewer), User + refute_permit users(:recruiter), User end end