diff --git a/app/models/stacks_media_stream.rb b/app/models/stacks_media_stream.rb
index 24c1e8b8..1efd5194 100644
--- a/app/models/stacks_media_stream.rb
+++ b/app/models/stacks_media_stream.rb
@@ -17,5 +17,5 @@ def file
def stacks_rights
@stacks_rights ||= StacksRights.new(id: id, file_name: file_name)
end
- delegate :rights, :restricted_by_location?, :stanford_restricted?, to: :stacks_rights
+ delegate :rights, :restricted_by_location?, :stanford_restricted?, :embargoed?, to: :stacks_rights
end
diff --git a/app/models/stacks_rights.rb b/app/models/stacks_rights.rb
index f406bcef..b0b21e64 100644
--- a/app/models/stacks_rights.rb
+++ b/app/models/stacks_rights.rb
@@ -33,6 +33,8 @@ def restricted_by_location?
rights.restricted_by_location?(file_name)
end
+ delegate :embargoed?, to: :rights
+
def object_thumbnail?
doc = Nokogiri::XML.parse(public_xml)
diff --git a/app/services/media_authentication_json.rb b/app/services/media_authentication_json.rb
index e0348d55..e55996a6 100644
--- a/app/services/media_authentication_json.rb
+++ b/app/services/media_authentication_json.rb
@@ -4,6 +4,10 @@
# A class to model various authentication checks on media objects
# and return a hash to be used as JSON in a controller response
class MediaAuthenticationJson
+ # @param [User] user
+ # @param [StacksMediaStream] media
+ # @param [String] auth_url the login url to send to the client if the user could login.
+ # @param [Ability] ability the CanCan ability object
def initialize(user:, media:, auth_url:, ability:)
@user = user
@media = media
@@ -11,56 +15,64 @@ def initialize(user:, media:, auth_url:, ability:)
@ability = ability
end
- def as_json(*)
- return stanford_or_location_response if location_grants_access? && stanford_grants_access?
- return location_only_response if location_grants_access?
- return stanford_only_response if stanford_grants_access?
+ class DenyResponse
+ def initialize(auth_url)
+ @auth_url = auth_url
+ @status = []
+ end
- {}
- end
+ attr_reader :status, :auth_url
- private
+ def as_json
+ return { status: }.compact_blank.merge(login_service) if stanford_restricted?
- attr_reader :auth_url, :media, :user, :ability
+ { status: }.compact_blank
+ end
- def location_only_response
- {
- status: [:location_restricted]
- }
- end
+ def login_service
+ {
+ service: {
+ '@id' => auth_url,
+ 'label' => 'Stanford-affiliated? Login to play'
+ }
+ }
+ end
- def stanford_only_response
- {
- status: [:stanford_restricted]
- }.merge(login_service)
- end
+ def stanford_restricted?
+ status.include?(:stanford_restricted)
+ end
- def stanford_or_location_response
- {
- status: [
- :stanford_restricted,
- :location_restricted
- ]
- }.merge(login_service)
- end
+ def add_stanford_restricted!
+ status << :stanford_restricted
+ end
- def login_service
- {
- service: {
- '@id' => auth_url,
- 'label' => 'Stanford-affiliated? Login to play'
- }
- }
+ def add_location_restricted!
+ status << :location_restricted
+ end
+
+ def add_embargo!
+ status << :embargoed
+ end
end
- def stanford_restricted?
- media.stanford_restricted?
+ def build_response
+ DenyResponse.new(auth_url).tap do |response|
+ response.add_stanford_restricted! if stanford_grants_access?
+ response.add_location_restricted! if location_grants_access?
+ response.add_embargo! if embargoed?
+ end
end
- def location_restricted?
- media.restricted_by_location?
+ def as_json(*)
+ build_response.as_json
end
+ private
+
+ attr_reader :auth_url, :media, :user, :ability
+
+ delegate :embargoed?, :stanford_restricted?, :restricted_by_location?, to: :media
+
def user_is_in_location?
ability.can? :access, media
end
@@ -70,6 +82,6 @@ def stanford_grants_access?
end
def location_grants_access?
- location_restricted? && !user_is_in_location?
+ restricted_by_location? && !user_is_in_location?
end
end
diff --git a/spec/requests/media_auth_request_spec.rb b/spec/requests/media_auth_request_spec.rb
index 69143cf1..551e13f6 100644
--- a/spec/requests/media_auth_request_spec.rb
+++ b/spec/requests/media_auth_request_spec.rb
@@ -3,81 +3,115 @@
require 'rails_helper'
RSpec.describe "Authentication for Media requests", type: :request do
-
- let(:user_no_loc_no_webauth) { User.new }
- let(:user_webauth_stanford_no_loc) { User.new(webauth_user: true, ldap_groups: %w(stanford:stanford)) }
let(:druid) { 'bb582xs1304' }
- describe "#auth_check" do
- let(:format) { 'mp4' }
- let(:public_xml) do
- <<-XML
-
- #{rights_xml}
-
- XML
+ let(:format) { 'mp4' }
+ let(:public_xml) do
+ <<-XML
+
+ #{rights_xml}
+
+ XML
+ end
+
+ let(:rights_xml) do
+ <<-EOF.strip_heredoc
+
+
+
+ Stanford
+
+
+
+ EOF
+ end
+
+ let(:mock_media) do
+ sms = StacksMediaStream.new(id: 'bb582xs1304', file_name: 'file', format: format)
+ allow(Purl).to receive(:public_xml).with('bb582xs1304').and_return(public_xml)
+ sms
+ end
+
+ before do
+ allow_any_instance_of(MediaController).to receive(:current_user).and_return(user)
+ allow_any_instance_of(MediaController).to receive(:current_media).and_return(mock_media)
+ end
+
+ context 'when the user is stanford authenticated' do
+ let(:user) { User.new(webauth_user: true, ldap_groups: %w(stanford:stanford)) }
+
+ it 'gets the success JSON and a token' do
+ get "/media/#{druid}/file.#{format}/auth_check"
+ expect(response.parsed_body['status']).to eq 'success'
+ expect(response.parsed_body['token']).to match(/^[%a-zA-Z0-9]+/)
end
+ end
+
+ context 'when the user is not authenticated' do
+ let(:user) { User.new }
- let(:rights_xml) do
- <<-EOF.strip_heredoc
-
-
-
- Stanford
-
-
-
- EOF
+ context 'stanford restricted' do
+ it 'indicates that the object is restricted in the json' do
+ get "/media/#{druid}/file.#{format}/auth_check"
+ expect(response.parsed_body['status']).to eq ['stanford_restricted']
+ end
end
- let(:mock_media) do
- sms = StacksMediaStream.new(id: 'bb582xs1304', file_name: 'file', format: format)
- allow(Purl).to receive(:public_xml).with('bb582xs1304').and_return(public_xml)
- sms
+ context 'location restricted' do
+ let(:rights_xml) do
+ <<-EOF.strip_heredoc
+
+
+
+ location1
+
+
+
+ EOF
+ end
+
+ it 'indicates that the object is location restricted in the json' do
+ get "/media/#{druid}/file.#{format}/auth_check"
+ expect(response.parsed_body['status']).to eq ['location_restricted']
+ end
end
- context 'when the user can read/stream the file' do
- it 'gets the success JSON and a token' do
- allow_any_instance_of(MediaController).to receive(:current_user).and_return(user_webauth_stanford_no_loc)
- allow_any_instance_of(MediaController).to receive(:current_media).and_return(mock_media)
- get "/media/#{druid}/file.#{format}/auth_check.js"
- body = JSON.parse(response.body)
- expect(body['status']).to eq 'success'
- expect(body['token']).to match(/^[%a-zA-Z0-9]+/)
+ context 'when the file is embargoed or stanford restricted' do
+ let(:rights_xml) do
+ <<-EOF.strip_heredoc
+
+
+
+ 2099-05-15
+ stanford
+
+
+
+ EOF
+ end
+
+ it 'indicates that the object is stanford restricted and embargoed in the json' do
+ get "/media/#{druid}/file.#{format}/auth_check"
+ expect(response.parsed_body['status']).to eq %w[stanford_restricted embargoed]
end
end
- context 'when the user cannot read/stream the file' do
- context 'stanford restricted' do
- it 'indicates that the object is restricted in the json' do
- allow_any_instance_of(MediaController).to receive(:current_user).and_return(user_no_loc_no_webauth)
- allow_any_instance_of(MediaController).to receive(:current_media).and_return(mock_media)
- get "/media/#{druid}/file.#{format}/auth_check.js"
- body = JSON.parse(response.body)
- expect(body['status']).to eq(['stanford_restricted'])
- end
+ context 'when the file is embargoed' do
+ let(:rights_xml) do
+ <<-EOF.strip_heredoc
+
+
+
+ 2099-05-15
+
+
+
+ EOF
end
- context 'location restricted' do
- let(:rights_xml) do
- <<-EOF.strip_heredoc
-
-
-
- location1
-
-
-
- EOF
- end
-
- it 'indicates that the object is location restricted in the json' do
- allow_any_instance_of(MediaController).to receive(:current_user).and_return(user_no_loc_no_webauth)
- allow_any_instance_of(MediaController).to receive(:current_media).and_return(mock_media)
- get "/media/#{druid}/file.#{format}/auth_check.js"
- body = JSON.parse(response.body)
- expect(body['status']).to eq(['location_restricted'])
- end
+ it 'indicates that the object is embargoed in the json' do
+ get "/media/#{druid}/file.#{format}/auth_check.js"
+ expect(response.parsed_body['status']).to eq ['embargoed']
end
end
end
diff --git a/spec/services/media_authentication_json_spec.rb b/spec/services/media_authentication_json_spec.rb
index 45f7bb52..2af9c62a 100644
--- a/spec/services/media_authentication_json_spec.rb
+++ b/spec/services/media_authentication_json_spec.rb
@@ -4,11 +4,11 @@
RSpec.describe MediaAuthenticationJson do
let(:media) do
- double(
- 'Media',
+ instance_double(
+ StacksMediaStream,
restricted_by_location?: false,
stanford_restricted?: false,
- location_rights: false
+ embargoed?: false
)
end
let(:ability) { Ability.new(user) }