From be6ad05e496d5cad6b879e0871663e8764c7071f Mon Sep 17 00:00:00 2001 From: Vokhmin Alexey V Date: Thu, 9 Apr 2015 02:06:55 +0300 Subject: [PATCH] #465: Added specs for AdvisoryPolicy, ArchPolicy, BuildListPolicy --- .../api/v1/advisories_controller.rb | 7 +- app/policies/advisory_policy.rb | 5 +- app/policies/project_policy.rb | 6 +- spec/policies/advisory_policy_spec.rb | 31 +++ spec/policies/arch_policy_spec.rb | 17 ++ spec/policies/build_list_policy_spec.rb | 263 ++++++++++++++++++ spec/spec_helper.rb | 2 + 7 files changed, 325 insertions(+), 6 deletions(-) create mode 100644 spec/policies/advisory_policy_spec.rb create mode 100644 spec/policies/arch_policy_spec.rb create mode 100644 spec/policies/build_list_policy_spec.rb diff --git a/app/controllers/api/v1/advisories_controller.rb b/app/controllers/api/v1/advisories_controller.rb index ad3fc4665..669ca036f 100644 --- a/app/controllers/api/v1/advisories_controller.rb +++ b/app/controllers/api/v1/advisories_controller.rb @@ -1,8 +1,8 @@ class Api::V1::AdvisoriesController < Api::V1::BaseController before_action :authenticate_user! - skip_before_action :authenticate_user!, only: [:index, :show] if APP_CONFIG['anonymous_access'] - before_action :load_advisory - before_action :load_build_list, only: [:create, :update] + skip_before_action :authenticate_user!, only: %i(index show) if APP_CONFIG['anonymous_access'] + before_action :load_advisory, only: %i(show update) + before_action :load_build_list, only: %i(create update) def index authorize :advisory @@ -14,6 +14,7 @@ class Api::V1::AdvisoriesController < Api::V1::BaseController end def create + authorize :advisory if @build_list.can_attach_to_advisory? && @build_list.associate_and_create_advisory(params[:advisory]) && @build_list.save diff --git a/app/policies/advisory_policy.rb b/app/policies/advisory_policy.rb index bdcf8ba3d..8b6bfed93 100644 --- a/app/policies/advisory_policy.rb +++ b/app/policies/advisory_policy.rb @@ -6,8 +6,9 @@ class AdvisoryPolicy < ApplicationPolicy alias_method :search?, :index? alias_method :show?, :index? - def update? - true + def create? + !user.guest? end + alias_method :update?, :create? end diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb index 60e1f745d..a2e8ff3c2 100644 --- a/app/policies/project_policy.rb +++ b/app/policies/project_policy.rb @@ -21,12 +21,13 @@ class ProjectPolicy < ApplicationPolicy alias_method :refs_list?, :show? def create? - return true if is_admin? return false if user.guest? + return true if is_admin? owner_policy.write? end def update? + return false if user.guest? is_admin? || owner? || local_admin? end alias_method :alias?, :update? @@ -41,10 +42,12 @@ class ProjectPolicy < ApplicationPolicy alias_method :schedule?, :update? def destroy? + return false if user.guest? is_admin? || owner? || record.owner.is_a?(Group) && record.owner.actors.exists?(actor_type: 'User', actor_id: user.id, role: 'admin') end def mass_import? + return false if user.guest? is_admin? || user.platforms.main.find{ |p| local_admin?(p) }.present? end @@ -57,6 +60,7 @@ class ProjectPolicy < ApplicationPolicy # for grack def write? + return false if user.guest? is_admin? || owner? || local_writer? end diff --git a/spec/policies/advisory_policy_spec.rb b/spec/policies/advisory_policy_spec.rb new file mode 100644 index 000000000..766ae822f --- /dev/null +++ b/spec/policies/advisory_policy_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper' + +RSpec.describe AdvisoryPolicy, type: :policy do + let(:advisory) { FactoryGirl.build(:advisory) } + subject { described_class } + + %i(index? search? show?).each do |perm| + permissions perm do + it "grants access to anonymous user" do + expect(subject).to permit(User.new, advisory) + end + + it "grants access to user" do + expect(subject).to permit(FactoryGirl.create(:user), advisory) + end + end + end + + %i(create? update?).each do |perm| + permissions perm do + it "denies access to anonymous user" do + expect(subject).not_to permit(User.new, advisory) + end + + it "grants access to user" do + expect(subject).to permit(FactoryGirl.create(:user), advisory) + end + end + end + +end diff --git a/spec/policies/arch_policy_spec.rb b/spec/policies/arch_policy_spec.rb new file mode 100644 index 000000000..b071d0be5 --- /dev/null +++ b/spec/policies/arch_policy_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' + +RSpec.describe ArchPolicy, type: :policy do + let(:arch) { FactoryGirl.build(:arch) } + subject { described_class } + + permissions :index? do + it "grants access to anonymous user" do + expect(subject).to permit(User.new, arch) + end + + it "grants access to user" do + expect(subject).to permit(FactoryGirl.create(:user), arch) + end + end + +end diff --git a/spec/policies/build_list_policy_spec.rb b/spec/policies/build_list_policy_spec.rb new file mode 100644 index 000000000..70ee752ee --- /dev/null +++ b/spec/policies/build_list_policy_spec.rb @@ -0,0 +1,263 @@ +require 'spec_helper' + +RSpec.describe BuildListPolicy, type: :policy do + let(:build_list) { FactoryGirl.build(:build_list) } + subject { described_class } + + permissions :index? do + it "grants access to anonymous user" do + expect(subject).to permit(User.new, build_list) + end + + it "grants access to user" do + expect(subject).to permit(FactoryGirl.create(:user), build_list) + end + end + + %i(show? read? log? everything? owned? everything? list?).each do |perm| + permissions perm do + it "grants access for creator" do + expect(subject).to permit(build_list.user, build_list) + end + + it "grants access if user can read project" do + allow_any_instance_of(ProjectPolicy).to receive(:show?).and_return(true) + expect(subject).to permit(User.new, build_list) + end + + it "denies access if user can not read project" do + allow_any_instance_of(ProjectPolicy).to receive(:show?).and_return(false) + expect(subject).to_not permit(User.new, build_list) + end + end + end + + %i(create? rerun_tests?).each do |perm| + permissions perm do + before do + allow_any_instance_of(ProjectPolicy).to receive(:write?).and_return(true) + allow_any_instance_of(PlatformPolicy).to receive(:show?).and_return(true) + end + + it "grants access to user" do + expect(subject).to permit(FactoryGirl.build(:user), build_list) + end + + it "denies access if project is not a package" do + build_list.project.is_package = false + expect(subject).to_not permit(User.new, build_list) + end + + it "denies access if user can not write to project" do + allow_any_instance_of(ProjectPolicy).to receive(:write?).and_return(false) + expect(subject).to_not permit(User.new, build_list) + end + + it "denies access if user can not read platform" do + allow_any_instance_of(PlatformPolicy).to receive(:show?).and_return(false) + expect(subject).to_not permit(User.new, build_list) + end + end + end + + permissions :dependent_projects? do + before do + allow_any_instance_of(BuildListPolicy).to receive(:create?).and_return(true) + end + + it "grants access to user" do + expect(subject).to permit(User.new, build_list) + end + + it "denies access if user can not to create build list" do + allow_any_instance_of(BuildListPolicy).to receive(:create?).and_return(false) + expect(subject).to_not permit(User.new, build_list) + end + + it "denies access if save_to_platform is not main" do + allow(build_list.save_to_platform).to receive(:main?).and_return(false) + expect(subject).to_not permit(User.new, build_list) + end + end + + permissions :publish_into_testing? do + before do + allow_any_instance_of(BuildListPolicy).to receive(:create?).and_return(true) + allow_any_instance_of(BuildListPolicy).to receive(:publish?).and_return(true) + allow(build_list).to receive(:can_publish_into_testing?).and_return(true) + end + + it "grants access to user" do + expect(subject).to permit(User.new, build_list) + end + + it "grants access if user can not to create but can publish build list" do + allow_any_instance_of(BuildListPolicy).to receive(:create?).and_return(false) + expect(subject).to permit(User.new, build_list) + end + + it "denies access if build is from old core" do + build_list.new_core = false + expect(subject).to_not permit(User.new, build_list) + end + + it "denies access if build can not be published" do + allow(build_list).to receive(:can_publish_into_testing?).and_return(false) + expect(subject).to_not permit(User.new, build_list) + end + + it "denies access if user can not to create and publish build list" do + allow_any_instance_of(BuildListPolicy).to receive(:create?).and_return(false) + allow_any_instance_of(BuildListPolicy).to receive(:publish?).and_return(false) + expect(subject).to_not permit(User.new, build_list) + end + + context 'for personal platform' do + before do + allow(build_list.save_to_platform).to receive(:main?).and_return(false) + end + + it "grants access to user" do + expect(subject).to permit(User.new, build_list) + end + + it "denies access if user can not to create but can publish build list" do + allow_any_instance_of(BuildListPolicy).to receive(:create?).and_return(false) + expect(subject).to_not permit(User.new, build_list) + end + end + end + + permissions :publish? do + before do + allow(build_list).to receive(:can_publish?).and_return(true) + end + + context 'build published' do + before do + allow(build_list).to receive(:build_published?).and_return(true) + end + + it "denies access to user" do + expect(subject).to_not permit(User.new, build_list) + end + + it "grants access to admin of platform" do + allow_any_instance_of(BuildListPolicy).to receive(:local_admin?). + with(build_list.save_to_platform).and_return(true) + expect(subject).to permit(User.new, build_list) + end + + it "grants access to member of repository" do + allow(build_list.save_to_repository).to receive_message_chain(:members, :exists?).and_return(true) + expect(subject).to permit(User.new, build_list) + end + end + + context 'build not published' do + it "denies access to user" do + expect(subject).to_not permit(User.new, build_list) + end + + it "grants access to admin of platform if publish_without_qa is disabled" do + build_list.save_to_repository.publish_without_qa = false + allow_any_instance_of(BuildListPolicy).to receive(:local_admin?). + with(build_list.save_to_platform).and_return(true) + + expect(subject).to permit(User.new, build_list) + end + + it "grants access if user can write to project" do + allow_any_instance_of(ProjectPolicy).to receive(:write?).and_return(true) + expect(subject).to permit(User.new, build_list) + end + end + end + + permissions :create_container? do + it "denies access to user" do + expect(subject).to_not permit(User.new, build_list) + end + + context 'user can write to project' do + before do + allow_any_instance_of(ProjectPolicy).to receive(:write?).and_return(true) + end + + it "grants access to user" do + expect(subject).to permit(User.new, build_list) + end + + it "denies access if build is from old core" do + build_list.new_core = false + expect(subject).to_not permit(User.new, build_list) + end + end + + context 'user admin of platform' do + before do + allow_any_instance_of(BuildListPolicy).to receive(:local_admin?). + with(build_list.save_to_platform).and_return(true) + end + + it "grants access to user" do + expect(subject).to permit(User.new, build_list) + end + + it "denies access if build is from old core" do + build_list.new_core = false + expect(subject).to_not permit(User.new, build_list) + end + end + end + + permissions :reject_publish? do + it "denies access to user" do + expect(subject).to_not permit(User.new, build_list) + end + + it "grants access if user can write to project" do + allow_any_instance_of(ProjectPolicy).to receive(:write?).and_return(true) + expect(subject).to permit(User.new, build_list) + end + + it "denies access to admin of platform" do + allow_any_instance_of(BuildListPolicy).to receive(:local_admin?). + with(build_list.save_to_platform).and_return(true) + expect(subject).to_not permit(User.new, build_list) + end + + context 'publish_without_qa is disabled' do + before do + build_list.save_to_repository.publish_without_qa = false + end + + it "denies access to user" do + expect(subject).to_not permit(User.new, build_list) + end + + it "denies access if user can write to project" do + allow_any_instance_of(ProjectPolicy).to receive(:write?).and_return(true) + expect(subject).to_not permit(User.new, build_list) + end + + it "grants access to admin of platform" do + allow_any_instance_of(BuildListPolicy).to receive(:local_admin?). + with(build_list.save_to_platform).and_return(true) + expect(subject).to permit(User.new, build_list) + end + end + end + + permissions :cancel? do + it "denies access to user" do + expect(subject).to_not permit(User.new, build_list) + end + + it "grants access if user can write to project" do + allow_any_instance_of(ProjectPolicy).to receive(:write?).and_return(true) + expect(subject).to permit(User.new, build_list) + end + end + +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a61e17058..fcf0b5993 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -3,6 +3,7 @@ ENV["RAILS_ENV"] ||= 'test' require File.expand_path("../../config/environment", __FILE__) require 'rspec/rails' require 'webmock/rspec' +require 'pundit/rspec' # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories. @@ -40,6 +41,7 @@ RSpec.configure do |config| config.before(:all) { init_test_root } config.after(:all) { clear_test_root } config.before { stub_redis } + config.before(type: :policy) { stub_symlink_methods } end def set_session_for(user=nil)