Skip to content

Commit

Permalink
Merge pull request #233 from cul/dlc-1171_restricted-images
Browse files Browse the repository at this point in the history
DLC-1171 restricted images
  • Loading branch information
barmintor authored Jan 16, 2025
2 parents 19c0552 + fe42465 commit 35699a2
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 12 deletions.
11 changes: 9 additions & 2 deletions app/controllers/concerns/iiif/authz/v2/bytestreams.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,22 @@ def probe_options
render body: nil
end

def has_probeable_resource?(solr_doc)
return false unless solr_doc.present?
resource_doc = resources_for_document(solr_doc, false).detect {|x| x[:id].split('/')[-1] == params[:bytestream_id]}
return true if resource_doc.present?
(solr_doc.fetch('dc_type_ssm',[]) & ['StillImage', 'Image']).present?
end

def probe
cors_headers(allow_origin: request_origin, allow_credentials: request_origin(false))
response.headers["Cache-Control"] = "no-cache, no-store"
@response, @document = fetch(params[:catalog_id])
resource_doc = resources_for_document(@document, false).detect {|x| x[:id].split('/')[-1] == params[:bytestream_id]}
if @document.nil? || resource_doc.nil?
unless has_probeable_resource?(@document)
render status: :not_found, plain: "resource not found"
return
end

remote_ip = DCV_CONFIG.dig('media_streaming','wowza', 'client_ip_override') || request.remote_ip
probe_response = Iiif::Authz::V2::ProbeService::Response.new(
document: @document, bytestream_id: params[:bytestream_id], ability_helper: self, route_helper: self,
Expand Down
5 changes: 5 additions & 0 deletions app/controllers/iiif/presentations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ class Iiif::PresentationsController < ApplicationController

self.search_service_class = Dcv::SearchService

# overrides the session role key from Cul::Omniauth::RemoteIpAbility
def current_ability
@current_ability ||= Ability.new(current_user, roles: session["cul.roles"], remote_ip:request.remote_ip)
end

def child_service
@children_adapter ||= Dcv::Solr::ChildrenAdapter.new(self, self, "title_ssm")
end
Expand Down
2 changes: 1 addition & 1 deletion app/helpers/children_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def memoized_structured_children(document)
end

def structured_children_for_document(document)
children = structured_children_from_solr(document) if document['structured_bsi'] == true
children = structured_children_from_solr(document)
unless children
children = document_children_from_model(document)[:children]
# just assign the order they came in, since there's no structure
Expand Down
2 changes: 2 additions & 0 deletions app/helpers/dcv/children_helper_behavior.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ def solr_children_adapter
end

def structured_children_from_solr(parent_document)
return solr_children_adapter.from_unordered_membership(parent_document) unless parent_document&.has_structure?

solr_children_adapter.from_all_structure_proxies(parent_document)
end

Expand Down
7 changes: 7 additions & 0 deletions app/models/iiif/authz/v2/probe_service/response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ def redirect_location_properties(ability_helper=@ability_helper)
format: 'application/vnd.apple.mpegurl'
}
end
if (@document.fetch('dc_type_ssm',[]) & ['StillImage', 'Image']).present?
return {
status: 302,
location: Dcv::Utils::CdnUtils.info_url(id: @document['fedora_pid_uri_ssi']&.split('/').last),
format: 'application/json+ld'
}
end
preferred_bytestream_id = Dcv::Utils::UrlUtils.preferred_content_bytestream(@document)
return { status: 302, location: route_helper.bytestream_content_url(catalog_id: @document.id, bytestream_id: preferred_bytestream_id) }
end
Expand Down
16 changes: 12 additions & 4 deletions app/models/iiif/manifest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,21 @@ def as_json(opts = {})
end

def items
return [] unless @solr_document

if @solr_document['active_fedora_model_ssi'] == 'GenericResource'
[canvas_for(@solr_document, route_helper, routing_opts, label[:en]).to_h]
else
children_service.from_all_structure_proxies(@solr_document).map do |canvas_document|
return [canvas_for(@solr_document, route_helper, routing_opts, label[:en]).to_h]
end

if @solr_document.has_structure?
return children_service.from_all_structure_proxies(@solr_document).map do |canvas_document|
canvas_for(canvas_document, route_helper, routing_opts).to_h
end.compact
end

children_service.from_unordered_membership(@solr_document).map do |canvas_document|
canvas_for(canvas_document, route_helper, routing_opts).to_h
end.compact
end

def routing_opts
Expand All @@ -173,7 +181,7 @@ def routing_opts
# continuous
def behaviors(items = nil)
return nil if @solr_document['active_fedora_model_ssi'] == 'GenericResource'
return [Iiif::Behavior::V3::UNORDERED] unless @solr_document['structured_bsi']
return [Iiif::Behavior::V3::UNORDERED] unless @solr_document.has_structure?

num_canvases = items&.length || @solr_document['cul_number_of_members_isi']
return [Iiif::Behavior::V3::INDIVIDUALS] if num_canvases.nil? || num_canvases < 2
Expand Down
7 changes: 4 additions & 3 deletions app/models/iiif/painting_annotation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def to_h

def annotation_body(routing_opts)
body = { 'type' => canvas.canvas_type }
catalog_id = canvas.solr_document.id
if body['type'] == Iiif::Type::V3::IMAGE
dimensions = canvas.dimensions.select {|k,h| k == :height or k == :width}.to_h.stringify_keys
body.merge!(IIIF_TEMPLATES['image_annotation_body'].deep_dup)
Expand All @@ -29,22 +30,22 @@ def annotation_body(routing_opts)
body['format'] = 'image/jpeg'
iiif_id = Dcv::Utils::CdnUtils.info_url(id: canvas.fedora_pid).sub(/\/info.json$/,'')
body['service'].first['@id'] = iiif_id
unless ability_helper.can_access_asset?(canvas.solr_document, Ability.new) # check if public
body['service'].first['service'] = [Iiif::Authz::V2::ProbeService.new(canvas, route_helper: route_helper, ability_helper: ability_helper)]
end
elsif body['type'] == Iiif::Type::V3::TEXT
body.merge!(IIIF_TEMPLATES['text_annotation_body'].deep_dup)
catalog_id = canvas.solr_document.id
bytestream_id = Dcv::Utils::UrlUtils.preferred_content_bytestream(canvas.solr_document)
body['id'] = route_helper.bytestream_content_url({catalog_id: catalog_id, filename: 'content.pdf', bytestream_id: bytestream_id, download: false})
body['service'] = [Iiif::Authz::V2::ProbeService.new(canvas, route_helper: route_helper, ability_helper: ability_helper)]
elsif body['type'] == Iiif::Type::V3::VIDEO || body['type'] == Iiif::Type::V3::SOUND
# use the video player for all AMI
body['type'] = Iiif::Type::V3::VIDEO
# media streaming with auth service
catalog_id = canvas.solr_document.id
bytestream_id = Dcv::Utils::UrlUtils.preferred_content_bytestream(canvas.solr_document)
body['id'] = route_helper.bytestream_resource_url(catalog_id: catalog_id, bytestream_id: bytestream_id)
body['service'] = [Iiif::Authz::V2::ProbeService.new(canvas, route_helper: route_helper, ability_helper: ability_helper)]
else
catalog_id = canvas.solr_document.id
filename = canvas.solr_document['label_ssi']
body['id'] = route_helper.bytestream_content_url({catalog_id: catalog_id, filename: filename, bytestream_id: 'content', download: true})
end
Expand Down
4 changes: 4 additions & 0 deletions app/models/solr_document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ def has_restriction?
self[:restriction_ssim].present?
end

def has_structure?
!!(self[:structured_bsi] || self[:datastreams_ssim]&.include?('structMetadata'))
end

def title
title_val = (TITLE_FIELDS.inject(nil) { |memo, field| memo || self[field]&.first }) || id
title_val.to_s.strip
Expand Down
11 changes: 11 additions & 0 deletions spec/models/iiif/authz/v2/probe_service/response_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
let(:token_authorizer) { instance_double(Iiif::Authz::V2::ProbeService::Response::TokenAuthorizer) }
let(:user) { instance_double(User) }
let(:probe_response_status) { probe_response.to_h[:status] }
let(:probe_response_location) { probe_response.to_h[:location] }
let(:probe_response_format) { probe_response.to_h[:format] }

before do
allow(controller).to receive(:current_user).and_return(user)
Expand All @@ -41,6 +43,15 @@
allow(controller).to receive(:bytestream_content_url)
end
it { expect(probe_response_status).to eql(302) }
context 'solr document is an image' do
let(:well_known_pid) { 'some:pid' }
let(:solr_hash) { { dc_type_ssm: ['StillImage'], id: well_known_pid, fedora_pid_uri_ssi: "info:fedora/#{well_known_pid}" } }
it 'returns a 302 for the image info doc' do
expect(probe_response_status).to eql(302)
expect(probe_response_location).to end_with("#{well_known_pid}/info.json")
expect(probe_response_format).to eql('application/json+ld')
end
end
end
context "not authorized" do
before do
Expand Down
4 changes: 2 additions & 2 deletions spec/models/iiif/manifest_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@
allow(ability_helper).to receive(:can?).and_return(true)
end

it 'delegates to children_service for structured list' do
expect(children_service).to receive(:from_all_structure_proxies).and_return(child_documents)
it 'delegates to children_service for child list' do
expect(children_service).to receive(:from_unordered_membership).and_return(child_documents)
expect(iiif_manifest.items.first&.dig('label', 'en')).to eql ['Child Document']
end
end
Expand Down
11 changes: 11 additions & 0 deletions spec/models/solr_document_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,15 @@
expect(solr_document.clean_resolver(na_https)).to eql(na_https)
end
end
describe '#has_structure?' do
it 'is true if structMetadata stream is listed' do
expect(SolrDocument.new(datastreams_ssim: ['structMetadata']).has_structure?).to be true
end
it 'is true if structure boolean is set' do
expect(SolrDocument.new(structured_bsi: true).has_structure?).to be true
end
it 'is otherwise false' do
expect(solr_document.has_structure?).to be false
end
end
end

0 comments on commit 35699a2

Please sign in to comment.