prevent non-authorized users to access medical release files
This commit is contained in:
@@ -48,8 +48,10 @@ class ContractsController < ApplicationController
|
|||||||
# Native release contracts must be generated on-the-fly; non-native releases have a contract attachment
|
# Native release contracts must be generated on-the-fly; non-native releases have a contract attachment
|
||||||
if releasable.native?
|
if releasable.native?
|
||||||
send_file contract.to_pdf, download_attributes
|
send_file contract.to_pdf, download_attributes
|
||||||
else
|
elsif policy(contract).show?
|
||||||
redirect_to releasable.contract.service_url
|
redirect_to releasable.contract.service_url
|
||||||
|
else
|
||||||
|
raise Pundit::NotAuthorizedError
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ class Contract
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def medical_release?
|
||||||
|
@releasable.instance_of?(MedicalRelease)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def contract_template
|
def contract_template
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
class ContractPolicy < ApplicationPolicy
|
class ContractPolicy < ApplicationPolicy
|
||||||
def show?
|
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
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -31,7 +31,11 @@ class MedicalReleasePolicy < ReleasePolicy
|
|||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def download_single?
|
||||||
|
user.account_manager?
|
||||||
|
end
|
||||||
|
|
||||||
def download_multiple?
|
def download_multiple?
|
||||||
true
|
download_single?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
<% if policy(medical_release.tags).new? %>
|
<% 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 %>
|
<%= link_to fa_icon("tags fw", text: "Tags"), [:new, medical_release, :acts_as_taggable_on_tag], class: "dropdown-item", remote: true %>
|
||||||
<% end %>
|
<% 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" %>
|
<%= link_to fa_icon("download fw", text: "Download"), [medical_release, :contracts, format: "pdf"], class: "dropdown-item", target: "_blank" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% if policy(medical_release).destroy? %>
|
<% if policy(medical_release).destroy? %>
|
||||||
|
|||||||
@@ -63,4 +63,55 @@ RSpec.describe ContractsController, type: :controller do
|
|||||||
|
|
||||||
it_behaves_like "a contracts controller"
|
it_behaves_like "a contracts controller"
|
||||||
end
|
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
|
end
|
||||||
|
|||||||
145
spec/features/user_managing_medical_releases_spec.rb
Normal file
145
spec/features/user_managing_medical_releases_spec.rb
Normal 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
|
||||||
Reference in New Issue
Block a user