process password protected pdf files
This commit is contained in:
committed by
Pete Matsyburka
parent
a573545ead
commit
e864e8a47f
@@ -0,0 +1,29 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module PdfUtils
|
||||
module_function
|
||||
|
||||
def encrypted?(data, password: nil)
|
||||
HexaPDF::Document.new(io: StringIO.new(data), decryption_opts: { password: })
|
||||
|
||||
false
|
||||
rescue HexaPDF::EncryptionError
|
||||
true
|
||||
end
|
||||
|
||||
def decrypt(data, password)
|
||||
encrypted_doc = HexaPDF::Document.new(io: StringIO.new(data), decryption_opts: { password: })
|
||||
|
||||
decrypted_doc = HexaPDF::Document.new
|
||||
|
||||
encrypted_doc.pages.each do |page|
|
||||
decrypted_doc.pages << decrypted_doc.import(page)
|
||||
end
|
||||
|
||||
decrypted_io = StringIO.new
|
||||
|
||||
decrypted_doc.write(decrypted_io, validate: false)
|
||||
|
||||
decrypted_io.tap(&:rewind).read
|
||||
end
|
||||
end
|
||||
@@ -5,6 +5,7 @@ module Templates
|
||||
PDF_CONTENT_TYPE = 'application/pdf'
|
||||
ANNOTATIONS_SIZE_LIMIT = 6.megabytes
|
||||
InvalidFileType = Class.new(StandardError)
|
||||
PdfEncrypted = Class.new(StandardError)
|
||||
|
||||
module_function
|
||||
|
||||
@@ -19,6 +20,15 @@ module Templates
|
||||
document = template.documents.create!(blob:)
|
||||
|
||||
if blob.content_type == PDF_CONTENT_TYPE && blob.metadata['pdf'].nil?
|
||||
data = maybe_decrypt_pdf_or_raise(document_data, params)
|
||||
|
||||
if data != document_data
|
||||
blob = ActiveStorage::Blob.create_and_upload!(
|
||||
io: StringIO.new(new_data), filename: blob.filename
|
||||
)
|
||||
document_data = data
|
||||
end
|
||||
|
||||
annotations =
|
||||
document_data.size > ANNOTATIONS_SIZE_LIMIT ? [] : Templates::BuildAnnotations.call(document_data)
|
||||
|
||||
@@ -41,6 +51,8 @@ module Templates
|
||||
data = file.read
|
||||
|
||||
if file.content_type == PDF_CONTENT_TYPE
|
||||
data = maybe_decrypt_pdf_or_raise(data, params)
|
||||
|
||||
annotations = data.size > ANNOTATIONS_SIZE_LIMIT ? [] : Templates::BuildAnnotations.call(data)
|
||||
metadata = { 'identified' => true, 'analyzed' => true,
|
||||
'sha256' => Base64.urlsafe_encode64(Digest::SHA256.digest(data)),
|
||||
@@ -56,6 +68,16 @@ module Templates
|
||||
end
|
||||
end
|
||||
|
||||
def maybe_decrypt_pdf_or_raise(data, params)
|
||||
if data.size < ANNOTATIONS_SIZE_LIMIT && PdfUtils.encrypted?(data)
|
||||
PdfUtils.decrypt(data, params[:password])
|
||||
else
|
||||
data
|
||||
end
|
||||
rescue HexaPDF::EncryptionError
|
||||
raise PdfEncrypted
|
||||
end
|
||||
|
||||
def handle_file_types(_document_data, blob)
|
||||
raise InvalidFileType, blob.content_type
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user