Class: Rubrik::Document

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/rubrik/document.rb,
lib/rubrik/document/increment.rb,
lib/rubrik/document/serialize_object.rb

Defined Under Namespace

Modules: Increment, SerializeObject

Constant Summary collapse

CONTENTS_PLACEHOLDER =
Object.new.freeze
BYTE_RANGE_PLACEHOLDER =
Object.new.freeze
SIGNATURE_SIZE =
8_192

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(input) ⇒ Document

Returns a new instance of Document.



32
33
34
35
36
37
38
39
40
41
42
# File 'lib/rubrik/document.rb', line 32

def initialize(input)
  self.io = input
  self.objects = PDF::Reader::ObjectHash.new(input)

  self.last_object_id = objects.trailer[:Size] - 1
  self.first_free_object_id = find_first_free_object_id

  self.modified_objects = []

  fetch_or_create_interactive_form!
end

Instance Attribute Details

#first_free_object_idObject

Returns the value of attribute first_free_object_id.



21
22
23
# File 'lib/rubrik/document.rb', line 21

def first_free_object_id
  @first_free_object_id
end

#ioObject

Returns the value of attribute io.



15
16
17
# File 'lib/rubrik/document.rb', line 15

def io
  @io
end

#last_object_idObject

Returns the value of attribute last_object_id.



27
28
29
# File 'lib/rubrik/document.rb', line 27

def last_object_id
  @last_object_id
end

#modified_objectsObject

Returns the value of attribute modified_objects.



24
25
26
# File 'lib/rubrik/document.rb', line 24

def modified_objects
  @modified_objects
end

#objectsObject

Returns the value of attribute objects.



18
19
20
# File 'lib/rubrik/document.rb', line 18

def objects
  @objects
end

Instance Method Details

#add_signature_fieldObject

Returns the reference of the Signature Value dictionary.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/rubrik/document.rb', line 46

def add_signature_field
  # To add an signature to the PDF, we need the following structure
  # Interactive Form -> Signature Field -> Signature Value
  signature_value_id = assign_new_object_id!
  modified_objects << {
    id: signature_value_id,
    value: {
      Type: :Sig,
      Filter: :"Adobe.PPKLite",
      SubFilter: :"adbe.pkcs7.detached",
      Contents: CONTENTS_PLACEHOLDER,
      ByteRange: BYTE_RANGE_PLACEHOLDER
    }
  }

  first_page_reference = T.must(objects.page_references[0])

  # create signature field
  signature_field_id = assign_new_object_id!
  modified_objects << {
    id: signature_field_id,
    value: {
      T: "Signature-#{SecureRandom.hex(2)}",
      FT: :Sig,
      V: signature_value_id,
      Type: :Annot,
      Subtype: :Widget,
      Rect: [0, 0, 0, 0],
      F: 4,
      P: first_page_reference
    }
  }

  first_page = objects.fetch(first_page_reference)
  annots = first_page[:Annots]

  if annots.is_a?(PDF::Reader::Reference)
    new_annots = objects.fetch(annots).dup
    new_annots << signature_field_id

    modified_objects << {id: annots, value: new_annots}
  else
    new_first_page = first_page.dup
    (new_first_page[:Annots] ||= []) << signature_field_id

    modified_objects << {id: first_page_reference, value: new_first_page}
  end

  fields_entry = interactive_form[:Fields]
  if fields_entry.is_a?(PDF::Reader::Reference)
    new_fields_array = objects.fetch(fields_entry).dup
    new_fields_array << signature_field_id

    modified_objects << {id: fields_entry, value: new_fields_array}
  else
    (interactive_form[:Fields] ||= []) << signature_field_id
  end

  signature_value_id
end