diff --git a/Gemfile b/Gemfile index 4371548..9264c4d 100644 --- a/Gemfile +++ b/Gemfile @@ -6,6 +6,7 @@ gem 'sinatra' # Gems for pdf generation gem 'pdfkit' gem 'wkhtmltopdf-binary' +gem 'origami' group :development, :test do gem 'awesome_print' diff --git a/Gemfile.lock b/Gemfile.lock index 2c63c6f..b857d80 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -15,6 +15,7 @@ GEM mime-types (3.1) mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) + origami (1.2.7) pdfkit (0.8.2) pony (1.11) mail (>= 2.0) @@ -47,6 +48,7 @@ PLATFORMS DEPENDENCIES awesome_print letter_opener + origami pdfkit pony pry diff --git a/pdf_test2016-06-26 14:46:02 UTC b/pdf_test2016-06-26 14:46:02 UTC deleted file mode 100644 index daed3f2..0000000 Binary files a/pdf_test2016-06-26 14:46:02 UTC and /dev/null differ diff --git a/report_generator.rb b/report_generator.rb index c1b434f..f1d71dd 100644 --- a/report_generator.rb +++ b/report_generator.rb @@ -3,10 +3,13 @@ require 'pry' unless ENV['RACK_ENV'] == 'production' require 'pony' require 'json' - +require 'openssl' +require 'origami' class ReportGenerator < Sinatra::Base + include Origami + use Rack::Auth::Basic, "Restricted Area" do |username, password| if ENV['RACK_ENV'] == 'production' @@ -27,8 +30,7 @@ class ReportGenerator < Sinatra::Base :from => 'noreply@receipt-yourself.com', :subject => 'hi', :body => "Hello there. It is #{DateTime.now}. Enjoy your KIF report.", - :attachments => {"KIF_report_#{DateTime.now}.pdf" => File.read(@file)}) - + :attachments => {"KIF_report_#{DateTime.now}.pdf" => File.read(@output_file)}) status 200 end @@ -39,7 +41,7 @@ class ReportGenerator < Sinatra::Base :from => 'noreply@receipt-yourself.com', :subject => 'hi', :body => "Hello there. It is #{DateTime.now}. Enjoy your KUF report.", - :attachments => {"KUF_report_#{DateTime.now}.pdf" => File.read(@file)}) + :attachments => {"KUF_report_#{DateTime.now}.pdf" => File.read(@output_file)}) status 200 end @@ -74,6 +76,71 @@ def generate_pdf(pdf_path) headers['Content-Type'] = 'application/pdf' @file_name = "pdf_test#{Time.now.getutc}" @file = kit.to_file(@file_name) + sign_pdf + end + + def sign_pdf + # Code below is based on documentation available on + # http://www.ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL.html + key = OpenSSL::PKey::RSA.new 2048 + + open 'private_key.pem', 'w' do |io| io.write key.to_pem end + open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end + + cipher = OpenSSL::Cipher::Cipher.new 'AES-128-CBC' + pass_phrase = if ENV['RACK_ENV'] == 'production' + ENV['PDF_PASSWORD'] + else + "admin" + end + + key_secure = key.export cipher, pass_phrase + + open 'private_key.pem', 'w' do |io| + io.write key_secure + end + + #Create the certificate + + name = OpenSSL::X509::Name.parse 'CN=PDF_signature' + + cert = OpenSSL::X509::Certificate.new + cert.version = 2 + cert.serial = 0 + cert.not_before = Time.now + cert.not_after = Time.now + 3600 + + cert.public_key = key.public_key + cert.subject = name + + + @output_file = "pdf_signed_test#{Time.now.getutc}" + + contents = ContentStream.new.setFilter(:FlateDecode) + contents.write @output_file, + :x => 350, + :y => 750, + :rendering => Text::Rendering::STROKE, + :size => 30 + + @pdf = PDF.read(@file) + + sigannot = Annotation::Widget::Signature.new + sigannot.Rect = Rectangle[:llx => 89.0, :lly => 386.0, :urx => 190.0, :ury => 353.0] + page = @pdf.get_page(1) + page.add_annot(sigannot) + + # Sign the PDF with the specified keys + @pdf.sign(cert, key, + :method => 'adbe.pkcs7.sha1', + :annotation => sigannot, + :location => "Serbia", + :contact => "besermenji@receiptyourself.com", + :reason => "Proof of Concept" + ) + + # Save the resulting file + @pdf.save(@output_file) end end \ No newline at end of file