Skip to content

Commit

Permalink
Item.create_zip_file() supports authorization
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Dolski committed Jan 5, 2024
1 parent 60dcac2 commit 302c0d3
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 16 deletions.
1 change: 1 addition & 0 deletions app/controllers/collections_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def all_files
metadata_profile: @collection.institution.default_metadata_profile,
download: download,
user: current_user,
request_context: request_context,
task: task)
redirect_to download_url(download)
else
Expand Down
4 changes: 3 additions & 1 deletion app/jobs/zip_items_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ class ZipItemsJob < ApplicationJob
# attribute is updated to reflect its filename within the application bucket.
#
# @param args [Hash] Hash with `:item_ids`, `:metadata_profile`, `:download`,
# `:user`, and `:task` keys.
# `:user`, `:request_context`, and `:task` keys.
# @see ZipBitstreamsJob
#
def perform(**args)
item_ids = args[:item_ids]
metadata_profile = args[:metadata_profile]
download = args[:download]
user = args[:user]
request_context = args[:request_context]
self.task = args[:task]
self.task&.update!(name: self.class.name,
download: download,
Expand All @@ -42,6 +43,7 @@ def perform(**args)
Item.create_zip_file(item_ids: item_ids,
metadata_profile: metadata_profile,
dest_key: download.object_key,
request_context: request_context,
task: self.task)
end
end
Expand Down
9 changes: 6 additions & 3 deletions app/models/item.rb
Original file line number Diff line number Diff line change
Expand Up @@ -215,14 +215,16 @@ def self.label_for(value)
# @param item_ids [Enumerable<Integer>]
# @param metadata_profile [MetadataProfile]
# @param dest_key [String] Destination key within the application bucket.
# @param request_context [RequestContext]
# @param print_progress [Boolean]
# @param task [Task] Optional.
#
def self.create_zip_file(item_ids:,
metadata_profile:,
dest_key:,
print_progress: false,
task: nil)
request_context:,
print_progress: false,
task: nil)
now = Time.now
count = item_ids.count
raise ArgumentError, "No items provided" if count < 1
Expand All @@ -245,7 +247,8 @@ def self.create_zip_file(item_ids:,
index = 0
item_ids.each do |item_id|
item = Item.find(item_id)
item.bitstreams.where.not(permanent_key: nil).each do |bs| # TODO: authorization
item.bitstreams.where.not(permanent_key: nil).each do |bs|
next unless BitstreamPolicy.new(request_context, bs).download?
dest_dir = File.join(stuffdir, item.handle&.handle || "#{item.id}")
FileUtils.mkdir_p(dest_dir)
dest_path = File.join(dest_dir, bs.filename)
Expand Down
18 changes: 12 additions & 6 deletions test/jobs/zip_items_job_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,24 @@ class ZipItemsJobTest < ActiveSupport::TestCase
end

test "perform() updates the Task given to it" do
item_ids = [items(:southeast_approved).id,
items(:southeast_multiple_bitstreams).id]
download = Download.create!(institution: institutions(:southeast))
institution = institutions(:southeast)
user = users(:southeast)
task = tasks(:pending)
item_ids = [items(:southeast_approved).id,
items(:southeast_multiple_bitstreams).id]
download = Download.create!(institution: institutions(:southeast))
institution = institutions(:southeast)
user = users(:southeast)
request_context = RequestContext.new(client_ip: "127.0.0.1",
client_hostname: "example.org",
user: user,
institution: institution,
role_limit: Role::NO_LIMIT)
task = tasks(:pending)

ZipItemsJob.perform_now(item_ids: item_ids,
metadata_profile: institution.default_metadata_profile,
download: download,
institution: institution,
user: user,
request_context: request_context,
task: task)

task.reload
Expand Down
59 changes: 53 additions & 6 deletions test/models/item_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,21 +77,35 @@ class ItemTest < ActiveSupport::TestCase
# create_zip_file()

test "create_zip_file() creates a zip file" do
item_ids = [items(:southeast_approved).id, items(:southeast_multiple_bitstreams).id]
dest_key = "institutions/test/downloads/file.zip"
item_ids = [items(:southeast_approved).id,
items(:southeast_multiple_bitstreams).id]
dest_key = "institutions/test/downloads/file.zip"
request_context = RequestContext.new(client_ip: "127.0.0.1",
client_hostname: "example.org",
user: users(:southeast),
institution: institutions(:southeast),
role_limit: Role::NO_LIMIT)
Item.create_zip_file(item_ids: item_ids,
metadata_profile: metadata_profiles(:southeast_default),
dest_key: dest_key)
dest_key: dest_key,
request_context: request_context)

assert ObjectStore.instance.object_exists?(key: dest_key)
end

test "create_zip_file() creates a zip file containing the expected files" do
item_ids = [items(:southeast_approved).id, items(:southeast_multiple_bitstreams).id]
dest_key = "institutions/test/downloads/file.zip"
item_ids = [items(:southeast_approved).id,
items(:southeast_multiple_bitstreams).id]
dest_key = "institutions/test/downloads/file.zip"
request_context = RequestContext.new(client_ip: "127.0.0.1",
client_hostname: "example.org",
user: users(:southeast),
institution: institutions(:southeast),
role_limit: Role::NO_LIMIT)
Item.create_zip_file(item_ids: item_ids,
metadata_profile: metadata_profiles(:southeast_default),
dest_key: dest_key)
dest_key: dest_key,
request_context: request_context)

Dir.mktmpdir do |tmpdir|
zip_file = File.join(tmpdir, "test.zip")
Expand All @@ -106,6 +120,39 @@ class ItemTest < ActiveSupport::TestCase
end
end

test "create_zip_file() respects user authorization" do
items = [items(:southeast_approved),
items(:southeast_multiple_bitstreams)]
bitstream_count = items.sum{ |it| it.bitstreams.count }
items[1].bitstreams.each do |bs|
bs.update!(role: Role::SYSTEM_ADMINISTRATOR)
end
item_ids = items.map(&:id)
dest_key = "institutions/test/downloads/file.zip"
request_context = RequestContext.new(client_ip: "127.0.0.1",
client_hostname: "example.org",
user: nil,
institution: institutions(:southeast),
role_limit: Role::NO_LIMIT)
Item.create_zip_file(item_ids: item_ids,
metadata_profile: metadata_profiles(:southeast_default),
dest_key: dest_key,
request_context: request_context)

Dir.mktmpdir do |tmpdir|
zip_file = File.join(tmpdir, "test.zip")
ObjectStore.instance.get_object(key: dest_key,
response_target: zip_file)
`cd #{tmpdir} && unzip #{zip_file}`
files = ZipUtils.archived_files(zip_file)
assert files.length < bitstream_count
csv_file = files.find{ |f| f[:name].end_with?(".csv") }
assert csv_file[:length] > 0
pdf_file = files.find{ |f| f[:name].end_with?(".pdf") }
assert pdf_file[:length] > 0
end
end

# all_access_embargoes()

test "all_access_embargoes() returns all all-access embargoes" do
Expand Down

0 comments on commit 302c0d3

Please sign in to comment.