prevent non-authorized users to access medical release files

This commit is contained in:
bilal
2020-06-18 14:33:49 +02:00
parent 988ef2beab
commit 88ec777299
7 changed files with 214 additions and 4 deletions

View File

@@ -48,8 +48,10 @@ class ContractsController < ApplicationController
# Native release contracts must be generated on-the-fly; non-native releases have a contract attachment
if releasable.native?
send_file contract.to_pdf, download_attributes
else
elsif policy(contract).show?
redirect_to releasable.contract.service_url
else
raise Pundit::NotAuthorizedError
end
end
end

View File

@@ -29,6 +29,10 @@ class Contract
}
end
def medical_release?
@releasable.instance_of?(MedicalRelease)
end
private
def contract_template

View File

@@ -1,5 +1,9 @@
class ContractPolicy < ApplicationPolicy
def show?
user.manager? || user.account_manager?
if record.respond_to?(:medical_release?) && record.medical_release?
user.account_manager?
else
user.manager? || user.account_manager?
end
end
end

View File

@@ -31,7 +31,11 @@ class MedicalReleasePolicy < ReleasePolicy
true
end
def download_single?
user.account_manager?
end
def download_multiple?
true
download_single?
end
end

View File

@@ -37,7 +37,7 @@
<% if policy(medical_release.tags).new? %>
<%= link_to fa_icon("tags fw", text: "Tags"), [:new, medical_release, :acts_as_taggable_on_tag], class: "dropdown-item", remote: true %>
<% end %>
<% if policy(Contract).show? && (medical_release.contract.attached? || medical_release.contract_template.present?) %>
<% if policy(MedicalRelease).download_single? && policy(Contract).show? && (medical_release.contract.attached? || medical_release.contract_template.present?) %>
<%= link_to fa_icon("download fw", text: "Download"), [medical_release, :contracts, format: "pdf"], class: "dropdown-item", target: "_blank" %>
<% end %>
<% if policy(medical_release).destroy? %>

View File

@@ -63,4 +63,55 @@ RSpec.describe ContractsController, type: :controller do
it_behaves_like "a contracts controller"
end
context "for medical releases" do
let(:native_releasable) { create(:medical_release_with_contract_template, :native) }
let(:non_native_releasable) { create(:medical_release_with_contract_template, :non_native) }
describe "#show when user is account manager" do
it_behaves_like "a contracts controller"
end
shared_examples "a medical contracts controller for non-authorized users" do
describe "#show" do
context "for a native release" do
it "responds with not authorized error" do
pdf_body = Tempfile.new
allow_any_instance_of(Contract).to receive(:to_pdf).and_return(pdf_body)
expect {
get :show, params: { format: :pdf, "#{native_releasable.model_name.singular}_id" => native_releasable }
}.to raise_exception(Pundit::NotAuthorizedError)
end
end
context "for a non-native release" do
it "responds with the attached contract" do
contract = double(:contract, service_url: "http://example.org/contract.pdf")
allow_any_instance_of(non_native_releasable.class).to receive(:contract).and_return(contract)
expect {
get :show, params: { format: :pdf, "#{non_native_releasable.model_name.singular}_id" => non_native_releasable }
}.to raise_exception(Pundit::NotAuthorizedError)
end
end
end
end
describe "#show when user is project manager" do
let(:manager_user) { create(:user, :manager) }
before do
sign_in manager_user
end
it_behaves_like "a medical contracts controller for non-authorized users"
end
describe "#show when user is associate" do
let(:associate_user) { create(:user, :associate) }
before do
sign_in associate_user
end
it_behaves_like "a medical contracts controller for non-authorized users"
end
end
end

View File

@@ -0,0 +1,145 @@
require "rails_helper"
feature "User managing medical releases" do
let(:current_user) { create(:user) }
let(:project) { create(:project, members: current_user, account: current_user.primary_account) }
context "when signed in as account manager" do
before do
sign_in current_user
end
scenario "Download All is visible" do
create(:medical_release_with_contract_template, :native, project: project)
create(:medical_release_with_contract_template, :non_native, project: project)
visit project_medical_releases_path(project)
expect(page).to have_content download_all_button
end
scenario "Download action in Manage menu is visible" do
create(:medical_release_with_contract_template, :native, project: project)
create(:medical_release_with_contract_template, :non_native, project: project)
visit project_medical_releases_path(project)
expect(page).to have_link("Download", exact: true, count: 2)
end
scenario "Downloading PDF of native medical release is possible" do
native_release = create(:medical_release_with_contract_template, :native, project: project)
visit project_medical_releases_path(project)
click_link *view_release_pdf_link_for(native_release)
expect(content_type).to eq('application/pdf')
end
end
context "when the user is manager(project manager)" do
let(:current_user) { create(:user, :manager) }
before do
sign_in current_user
end
scenario "Download All is not visible" do
create(:medical_release_with_contract_template, :native, project: project)
create(:medical_release_with_contract_template, :non_native, project: project)
visit project_medical_releases_path(project)
expect(page).not_to have_content download_all_button
end
scenario "Download action in Manage menu is not visible" do
create(:medical_release_with_contract_template, :native, project: project)
create(:medical_release_with_contract_template, :non_native, project: project)
visit project_medical_releases_path(project)
expect(page).to have_link("Download", exact: true, count: 0)
end
scenario "Downloading PDF of native medical release is not possible" do
native_release = create(:medical_release_with_contract_template, :native, project: project)
visit project_medical_releases_path(project)
link = medical_release_contracts_path(native_release, format: 'pdf')
expect { visit link }.to raise_exception Pundit::NotAuthorizedError
end
scenario "Downloading PDF of non native medical release is not possible" do
non_native_release = create(:medical_release_with_contract_template, :non_native, project: project)
visit project_medical_releases_path(project)
link = medical_release_contracts_path(non_native_release, format: 'pdf')
expect { visit link }.to raise_exception Pundit::NotAuthorizedError
end
end
context "when the user is associate" do
let(:current_user) { create(:user, :associate) }
before do
sign_in current_user
end
scenario "Download All is not visible" do
create(:medical_release_with_contract_template, :native, project: project)
create(:medical_release_with_contract_template, :non_native, project: project)
visit project_medical_releases_path(project)
expect(page).not_to have_content download_all_button
end
scenario "Download action in Manage menu is not visible" do
create(:medical_release_with_contract_template, :native, project: project)
create(:medical_release_with_contract_template, :non_native, project: project)
visit project_medical_releases_path(project)
expect(page).to have_link("Download", exact: true, count: 0)
end
scenario "Downloading PDF of native medical release is not possible" do
native_release = create(:medical_release_with_contract_template, :native, project: project)
visit project_medical_releases_path(project)
link = medical_release_contracts_path(native_release, format: 'pdf')
expect { visit link }.to raise_exception Pundit::NotAuthorizedError
end
scenario "Downloading PDF of non native medical release is not possible" do
non_native_release = create(:medical_release_with_contract_template, :non_native, project: project)
visit project_medical_releases_path(project)
link = medical_release_contracts_path(non_native_release, format: 'pdf')
expect { visit link }.to raise_exception Pundit::NotAuthorizedError
end
end
private
def download_all_button
'Download All'
end
def download_action
'Download'
end
def manage_button
t 'medical_releases.medical_release.actions.manage'
end
def view_release_pdf_link_for(release)
['Download', href: medical_release_contracts_path(release, format: 'pdf')]
end
end