Skip to content

Commit

Permalink
Encrypt document method
Browse files Browse the repository at this point in the history
  • Loading branch information
aldosolorzano committed Jan 17, 2019
1 parent 253a01b commit 803ac7a
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 2 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ rvm:
- 2.1
- 2.2
- 2.3.0
- 2.4.0
notifications:
email:
on_success: change
Expand Down
29 changes: 29 additions & 0 deletions lib/mifiel/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,49 @@ def self.create(args)
callback_url = args[:callback_url]
raise ArgumentError, 'Either file or hash must be provided' if !file && !hash
raise ArgumentError, 'Only one of file or hash must be provided' if file && hash
return Mifiel::Document.create_encrypted(args.dup) if args[:encrypted]
payload = {
signatories: build_signatories(signatories),
callback_url: callback_url,
file: (File.new(file) if file),
original_hash: hash,
name: name
}
payload[:encrypted] = true if args[:file].last(3) == 'der'
payload = args.merge(payload)
payload.reject! { |_k, v| v.nil? }
response = process_request('/documents', :post, payload)
Mifiel::Document.new(JSON.parse(response))
end
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize

def self.create_encrypted(args)
pdf = File.read(args[:file]) if args[:file]
password = Mifiel::Crypto::PBE.random_password
encrypted = Mifiel::Crypto.encrypt(pdf, password).to_der
e_path = "#{args[:file]}.der"
File.open(e_path, 'wb+') { |f| f.write(encrypted) }
args[:file] = e_path
args.delete(:encrypted)
document = Mifiel::Document.create(args)
payload = { signatories: encrypt_password(document.signers, password) }
response = process_request("/documents/#{document.id}", :put, payload)
Mifiel::Document.new(JSON.parse(response))
ensure
File.unlink(e_path) if File.exists?(e_path)
end

def self.encrypt_password(signers, password)
signers.map do |s|
e_passwords = s['e2ee']['group'].map do |k, e|
key = Mifiel::Crypto::ECIES.public_from_hex(e['pub'])
ecies = Mifiel::Crypto::ECIES.new
[k, { e_pass: ecies.encrypt(key, password).bth }]
end.to_h
[s['id'], e_passwords]
end.to_h
end

def request_signature(email, cc: nil)
params = { email: email }
params[:cc] = cc if cc.is_a?(Array)
Expand Down
2 changes: 1 addition & 1 deletion mifiel.gemspec
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'rubocop', '0.47.1'
spec.add_development_dependency 'simplecov', '~> 0.15'
spec.add_development_dependency 'sinatra', '~> 1.4', '>= 1.4.7'
spec.add_development_dependency 'webmock', '~> 1.22', '>= 1.22.2'
spec.add_development_dependency 'webmock', '~> 2.3.2', '>= 2.3.2'
end
41 changes: 41 additions & 0 deletions spec/mifiel/document_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,47 @@

it { expect(documents.status).to eq 'success' }
end

let(:params) do
{
file: 'spec/fixtures/example.pdf',
encrypted: true,
signatories: [
{ name: 'Signer 1', email: 'signer1@email.com', tax_id: 'AAA010101AAA' },
{ name: 'Signer 2', email: 'signer2@email.com', tax_id: 'AAA010102AAA' }
]
}
end

context 'create encrypted document with encrypted: true' do
let(:document) { Mifiel::Document.create(params) }
# it { expect(Mifiel::Document).to have_received(:create_ecnrypted).once }
it { expect(document).to be_a(Mifiel::Document) }
it { expect(File.exists?(params[:file] + '.der')).to be false }
end

context 'create_encrypted method' do
let(:document) { Mifiel::Document.create_encrypted(params) }
# it { expect(Mifiel::Document).to have_received(:create).once }
# it { expect(Mifiel::Document).to have_received(:encrypt_password).once }
it { expect(document).to be_a(Mifiel::Document) }
it { expect(File.exists?(params[:file] + '.der')).to be false }
end

context 'encrypt password with public keys' do
let!(:document) { Mifiel::Document.create_encrypted(params) }
let(:passwords) { Mifiel::Document.encrypt_password(document.signers, '1234567890') }
it 'should encrypt e_client & e_user passwords' do
passwords.each do |k, v|
expect(v['e_client'][:e_pass]).to be_a String
expect(v['e_client'][:e_pass]).to be_truthy
expect(v['e_client'][:e_pass].length).to eq 258
expect(v['e_user'][:e_pass]).to be_a String
expect(v['e_user'][:e_pass]).to be_truthy
expect(v['e_user'][:e_pass].length).to eq 258
end
end
end
end

describe 'working with a document' do
Expand Down
21 changes: 20 additions & 1 deletion spec/support/fake_mifiel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ class FakeMifiel < Sinatra::Base
{ widget_id: '123bc', success: true }.to_json
end

put '/api/v1/documents/:id' do
content_type :json
status 200
document.to_json
end

private

def template(args = {})
Expand All @@ -131,7 +137,7 @@ def key(args={})
# rubocop:disable Metrics/MethodLength
def document(args={})
id = args[:id] || SecureRandom.uuid
{
doc = {
id: id,
original_hash: Digest::SHA256.hexdigest(id),
file_file_name: 'test-pdf.pdf',
Expand All @@ -149,6 +155,7 @@ def document(args={})
file_signed_download: "/api/v1/documents/#{id}/file_signed?download=true",
file_zipped: "/api/v1/documents/#{id}/zip",
signatures: [{
id: SecureRandom.uuid,
email: 'signer1@email.com',
signed: true,
signed_at: (Time.now.utc - 10_000).iso8601,
Expand All @@ -161,5 +168,17 @@ def document(args={})
}
}]
}
e2ee = {
e_index: 0,
group: {
e_client:{ pub:"02e47233754d5abae537aebf2efa9b13410b811a270363f4a685e5ccd049fee627" },
e_user:{ pub:"02e47233754d5abae537aebf2efa9b13410b811a270363f4a685e5ccd049fee627" }
}
}
doc[:signers] = doc[:signatures]
doc[:signers].first.merge!({ e2ee: e2ee })
doc
end
end


0 comments on commit 803ac7a

Please sign in to comment.