mifiel 1.0.3 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 202e1a5ee696fcd1a42eba6aeedd9faf8906dce0
4
- data.tar.gz: 8e339531052e3a140214567254c4d354554b174f
3
+ metadata.gz: 824c42905ab5539e1400765da354b7856b0867c5
4
+ data.tar.gz: b14bf9cd247bcb5908a236809f7a8d2b62d9585b
5
5
  SHA512:
6
- metadata.gz: a3139f2aa18d3856386e9204f95cd1662c3a0a2b8acc9425a6dd482dd8fc30a91bf2aba1730152644b81a97488b57faf5fb2eebb6a692c7fac7920dc5d6c3987
7
- data.tar.gz: df4d1ac6f776051e549913e2e1f2d7d166e53aee7d87d2ff8913d6ee26e55fbffa71f8df9a69718b55522bd6e4cb5867b5c987327dd3e16497981c43a7e1e873
6
+ metadata.gz: c4967e263f0c34aa45c82e9771a2e3c53c9d894ff86b6cdc504a2c439c45de8e649b61966a8f905503c15af164de2128b7945ccb9d35d148b1da66d20058d0ef
7
+ data.tar.gz: 98a35a5cb8eca9ec7855fb52c4e110b7a3bfb5b8068a8feb8a51cd6e10c9e966c318e53e54572784daa38bbf26ec85b2b8e52f70c71a04e77ca0fb011b98fef4
data/.gitignore CHANGED
@@ -13,3 +13,6 @@
13
13
  *.a
14
14
  mkmf.log
15
15
  rubocop.html
16
+ .ruby-gemset
17
+ .ruby-version
18
+ *.sublime-workspace
data/Gemfile CHANGED
@@ -2,3 +2,13 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in mifiel.gemspec
4
4
  gemspec
5
+
6
+ group :development, :test do
7
+ gem 'coveralls', require: false
8
+ gem 'guard', '2.13.0'
9
+ gem 'guard-rspec'
10
+ # compatible with ruby 2.2.1
11
+ gem 'listen', '3.1.1'
12
+ gem 'guard-rubocop'
13
+ gem 'terminal-notifier-guard'
14
+ end
@@ -0,0 +1,37 @@
1
+ notification :terminal_notifier
2
+
3
+ rspec_options = {
4
+ all_after_pass: false,
5
+ cmd: 'rspec spec',
6
+ failed_mode: :focus
7
+ }
8
+
9
+ clearing :on
10
+
11
+ guard :rspec, rspec_options do
12
+ require 'ostruct'
13
+
14
+ # Generic Ruby apps
15
+ rspec = OpenStruct.new
16
+ rspec.spec = ->(m) { "spec/#{m}_spec.rb" }
17
+ rspec.spec_dir = 'spec'
18
+ rspec.spec_helper = 'spec/spec_helper.rb'
19
+
20
+ watch(%r{^spec/.+_spec\.rb$})
21
+ watch(%r{^lib/mifiel/(.+)\.rb$}) do |m|
22
+ "spec/mifiel/#{m[1]}_spec.rb"
23
+ end
24
+ watch(%r{^lib/mifiel/(.+)\.rb$}) do |m|
25
+ "spec/mifiel/integration/#{m[1]}_spec.rb"
26
+ end
27
+ watch(rspec.spec_helper) { rspec.spec_dir }
28
+ end
29
+
30
+ rubocop_opts = {
31
+ all_on_start: false,
32
+ cli: '--format html -o rubocop.html'
33
+ }
34
+ guard :rubocop, rubocop_opts do
35
+ watch(/.+\.rb$/)
36
+ watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
37
+ end
data/README.md CHANGED
@@ -58,9 +58,14 @@ Document methods:
58
58
 
59
59
  - Create:
60
60
 
61
+ > Use only **hash** if you dont want us to have the file.<br>
62
+ > Either **file** or **hash** must be provided.
63
+
61
64
  ```ruby
62
65
  document = Mifiel::Document.create(
63
66
  file: 'path/to/my-file.pdf',
67
+ # OR
68
+ hash: Digest::SHA256.hexdigest(File.read('path/to/my-file.pdf')),
64
69
  signatories: [
65
70
  { name: 'Signer 1', email: 'signer1@email.com', tax_id: 'AAA010101AAA' },
66
71
  { name: 'Signer 2', email: 'signer2@email.com', tax_id: 'AAA010102AAA' }
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'bundler/gem_tasks'
2
2
 
3
3
  task :console do
4
- exec 'irb -r mifiel -I ./lib'
4
+ exec 'pry -r mifiel -I ./lib'
5
5
  end
@@ -5,12 +5,12 @@ module Mifiel
5
5
  after_request :rescue_errors
6
6
 
7
7
  def rescue_errors(_name, response)
8
- if response.status == 400 # bad request
8
+ if (400..499).cover?(response.status)
9
9
  result = JSON.load(response.body)
10
10
  message = result['errors'] || [result['error']]
11
- fail BadRequestError, message.to_a.join(', ')
11
+ raise BadRequestError, message.to_a.join(', ')
12
12
  elsif (500..599).cover?(response.status)
13
- fail ServerError, "Could not process your request: status #{response.status}"
13
+ raise ServerError, "Could not process your request: status #{response.status}"
14
14
  end
15
15
  end
16
16
  end
@@ -7,94 +7,40 @@ module Mifiel
7
7
  put :save, '/documents/:id'
8
8
  delete :delete, '/documents/:id'
9
9
 
10
- def self.create(signatories:, file:nil, hash:nil, callback_url:nil)
11
- fail ArgumentError, 'Either file or hash must be provided' if !file && !hash
12
- fail ArgumentError, 'Only one of file or hash must be provided' if file && hash
13
- sgries = {}
14
- signatories.each_with_index { |s, i| sgries[i] = s }
15
- rest_request = RestClient::Request.new(
16
- url: "#{Mifiel.config.base_url}/documents",
17
- method: :post,
18
- payload: {
19
- file: File.new(file),
20
- original_hash: hash,
21
- signatories: sgries,
22
- callback_url: callback_url
23
- },
24
- ssl_version: 'SSLv23'
25
- )
26
- req = ApiAuth.sign!(rest_request, Mifiel.config.app_id, Mifiel.config.app_secret)
27
- JSON.load(req.execute)
28
- end
29
-
30
- def sign(certificate_id:nil, certificate:nil)
31
- fail ArgumentError, 'Either certificate_id or certificate must be provided' if !certificate_id && !certificate
32
- fail ArgumentError, 'Only one of certificate_id or certificate must be provided' if certificate_id && certificate
33
- fail NoSignatureError, 'You must first call build_signature or provide a signature' unless signature
34
- params = { signature: signature }
35
- params[:key] = certificate_id if certificate_id
36
- if certificate
37
- params[:certificate] = if certificate.encoding.to_s == 'UTF-8'
38
- certificate.unpack('H*')[0]
39
- else
40
- certificate
41
- end
42
- end
43
-
44
- Mifiel::Document._request("#{Mifiel.config.base_url}/documents/#{id}/sign", :post, params)
45
- rescue ActiveRestClient::HTTPClientException => e
46
- message = e.result.errors || [e.result.error]
47
- raise MifielError, message.to_a.join(', ')
48
- rescue ActiveRestClient::HTTPServerException
49
- raise MifielError, 'Server could not process request'
10
+ def self.create(signatories:, file: nil, hash: nil, callback_url: nil)
11
+ raise ArgumentError, 'Either file or hash must be provided' if !file && !hash
12
+ raise ArgumentError, 'Only one of file or hash must be provided' if file && hash
13
+ payload = {
14
+ signatories: build_signatories(signatories),
15
+ callback_url: callback_url,
16
+ file: (File.new(file) if file),
17
+ original_hash: hash
18
+ }
19
+ process_request('/documents', :post, payload)
50
20
  end
51
21
 
52
- def request_signature(email, cc:nil)
22
+ def request_signature(email, cc: nil)
53
23
  params = { email: email }
54
24
  params[:cc] = cc if cc.is_a?(Array)
55
25
  Mifiel::Document._request("#{Mifiel.config.base_url}/documents/#{id}/request_signature", :post, params)
56
- rescue ActiveRestClient::HTTPClientException => e
57
- message = e.result.errors || [e.result.error]
58
- raise MifielError, message.to_a.join(', ')
59
- rescue ActiveRestClient::HTTPServerException
60
- raise MifielError, 'Server could not process request'
61
26
  end
62
27
 
63
- def build_signature(private_key, private_key_pass)
64
- self.signature ||= sign_hash(private_key, private_key_pass, original_hash)
28
+ def self.process_request(path, method, payload)
29
+ path[0] = '' if path[0] == '/'
30
+ rest_request = RestClient::Request.new(
31
+ url: "#{Mifiel.config.base_url}/#{path}",
32
+ method: method,
33
+ payload: payload,
34
+ ssl_version: 'SSLv23'
35
+ )
36
+ req = ApiAuth.sign!(rest_request, Mifiel.config.app_id, Mifiel.config.app_secret)
37
+ JSON.load(req.execute)
65
38
  end
66
39
 
67
- private
68
-
69
- # Sign the provided hash
70
- # @param key [String] The contents of the .key file (File.read(...))
71
- # @param pass [String] The password of the key
72
- # @param hash [String] The hash or string to sign
73
- #
74
- # @return [String] Hex string of the signature
75
- def sign_hash(key, pass, hash)
76
- private_key = build_private_key(key, pass)
77
- unless private_key.private?
78
- fail NotPrivateKeyError, 'The private key is not valid'
79
- end
80
- signature = private_key.sign(OpenSSL::Digest::SHA256.new, hash)
81
- signature.unpack('H*')[0]
82
- end
83
-
84
- def build_private_key(private_data, key_pass)
85
- # create file so we can converted to pem
86
- private_file = File.new("./tmp/tmp-#{rand(1000)}.key", 'w+')
87
- private_file.write(private_data.force_encoding('UTF-8'))
88
- private_file.close
89
-
90
- key2pem_command = "openssl pkcs8 -in #{private_file.path} -inform DER -passin pass:#{key_pass}"
91
- priv_pem_s, error, status = Open3.capture3(key2pem_command)
92
-
93
- # delete file from file system
94
- File.unlink private_file.path
95
- fail PrivateKeyError, "#{error}, #{status}" unless error.empty?
96
-
97
- OpenSSL::PKey::RSA.new priv_pem_s
98
- end
40
+ def self.build_signatories(signatories)
41
+ sgries = {}
42
+ signatories.each_with_index { |s, i| sgries[i] = s }
43
+ sgries
44
+ end
99
45
  end
100
46
  end
@@ -1,3 +1,3 @@
1
1
  module Mifiel
2
- VERSION = '1.0.3'.freeze
2
+ VERSION = '1.1.0'.freeze
3
3
  end
@@ -0,0 +1,22 @@
1
+ {
2
+
3
+ "folders":
4
+ [
5
+ {
6
+ "file_exclude_patterns":
7
+ [
8
+ "*.sublime-workspace"
9
+ ],
10
+ "folder_exclude_patterns":
11
+ [
12
+ "coverage",
13
+ ".bundle",
14
+ "tmp"
15
+ ],
16
+ "follow_symlinks": true,
17
+ "path": ".",
18
+ "tab_size": 2,
19
+ "translate_tabs_to_spaces": false,
20
+ }
21
+ ]
22
+ }
@@ -32,4 +32,5 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency 'webmock', '~> 1.22', '>= 1.22.2'
33
33
  spec.add_development_dependency 'sinatra', '~> 1.4', '>= 1.4.7'
34
34
  spec.add_development_dependency 'rubocop', '~> 0.36'
35
+ spec.add_development_dependency 'simplecov', '~> 0.11'
35
36
  end
@@ -0,0 +1,31 @@
1
+ describe Mifiel::Base do
2
+ describe 'rescue_errors' do
3
+ describe 'when bad request' do
4
+ it 'should raise error' do
5
+ base = Mifiel::Base.new
6
+ expect do
7
+ base.rescue_errors('blah', FakeResponse.new(400))
8
+ end.to raise_error(Mifiel::BadRequestError)
9
+ end
10
+ end
11
+
12
+ describe 'when server error' do
13
+ it 'should raise error' do
14
+ base = Mifiel::Base.new
15
+ expect do
16
+ base.rescue_errors('blah', FakeResponse.new(500))
17
+ end.to raise_error(Mifiel::ServerError)
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ class FakeResponse
24
+ attr_reader :status,
25
+ :body
26
+
27
+ def initialize(status)
28
+ @status = status
29
+ @body = '{"body": "some response"}'
30
+ end
31
+ end
@@ -0,0 +1,12 @@
1
+ describe Mifiel::Certificate do
2
+ describe '#create' do
3
+ let(:certificate) do
4
+ Mifiel::Certificate.create(
5
+ 'spec/fixtures/FIEL_AAA010101AAA.cer'
6
+ )
7
+ end
8
+
9
+ it { expect(certificate).to be_a(Hash) }
10
+ end
11
+
12
+ end
@@ -19,83 +19,40 @@ describe Mifiel::Document do
19
19
  end
20
20
  end
21
21
 
22
- describe '#sign' do
23
- let!(:signature) { 'signature' }
22
+ describe '#request_signature' do
24
23
  let!(:document) { Mifiel::Document.all.first }
25
- let!(:certificate_id) { SecureRandom.uuid }
24
+ let!(:error_body) { { errors: ['some error'] }.to_json }
26
25
 
27
- context 'without build_signature first called' do
28
- it do
29
- expect do
30
- document.sign(certificate_id: certificate_id)
31
- end.to raise_error(Mifiel::NoSignatureError)
32
- end
33
- end
34
-
35
- context 'with build_signature called before' do
36
- it do
37
- document.build_signature(private_key, private_key_pass)
38
- expect do
39
- document.sign(certificate_id: certificate_id)
40
- end.not_to raise_error
41
- end
42
- end
43
-
44
- context 'with signature' do
45
- it do
46
- document.signature = signature
47
- expect do
48
- document.sign(certificate_id: certificate_id)
49
- end.not_to raise_error
50
- end
51
- end
52
-
53
- context 'with certificate' do
54
- it do
55
- document.build_signature(private_key, private_key_pass)
56
- expect do
57
- document.sign(certificate: certificate)
58
- end.not_to raise_error
59
- end
26
+ it '' do
27
+ expect do
28
+ document.request_signature('some@email.com')
29
+ end.not_to raise_error
60
30
  end
61
31
 
62
- context 'with certificate in hex' do
63
- it do
64
- document.build_signature(private_key, private_key_pass)
65
- expect do
66
- document.sign(certificate: certificate.unpack('H*')[0])
67
- end.not_to raise_error
32
+ context 'when bad request' do
33
+ before do
34
+ url = %r{mifiel.com\/api\/v1\/documents\/#{document.id}\/request_signature}
35
+ stub_request(:post, url).to_return(body: error_body, status: 404)
68
36
  end
69
- end
70
- end
71
37
 
72
- describe '#build_signature' do
73
- let!(:document) { Mifiel::Document.all.first }
74
-
75
- context 'with a wrong private_key' do
76
- it do
38
+ it '' do
77
39
  expect do
78
- document.build_signature('asd', private_key_pass)
79
- end.to raise_error(Mifiel::PrivateKeyError)
40
+ document.request_signature('some@email.com')
41
+ end.to raise_error(Mifiel::BadRequestError)
80
42
  end
81
43
  end
82
44
 
83
- context 'with a private_key that is not a private_key' do
84
- xit do
85
- cer = OpenSSL::X509::Certificate.new(certificate)
86
- expect do
87
- document.build_signature(cer.public_key.to_der, private_key_pass)
88
- end.to raise_error(Mifiel::NotPrivateKeyError)
45
+ context 'when server error' do
46
+ before do
47
+ url = %r{mifiel.com\/api\/v1\/documents\/#{document.id}\/request_signature}
48
+ stub_request(:post, url).to_return(body: error_body, status: 500)
89
49
  end
90
- end
91
50
 
92
- context 'with a wrong password' do
93
- it do
51
+ it '' do
94
52
  expect do
95
- document.build_signature('asd', private_key_pass)
96
- end.to raise_error(Mifiel::PrivateKeyError)
53
+ document.request_signature('some@email.com')
54
+ end.to raise_error(Mifiel::ServerError)
97
55
  end
98
56
  end
99
57
  end
100
-
101
58
  end
@@ -4,6 +4,13 @@ require 'pry-byebug'
4
4
  require 'mifiel'
5
5
  require 'webmock/rspec'
6
6
 
7
+ require 'simplecov'
8
+ require 'coveralls'
9
+ SimpleCov.start do
10
+ add_filter '/spec/'
11
+ end
12
+ Coveralls.wear!
13
+
7
14
  Dir['./spec/support/**/*.rb'].each { |f| require f }
8
15
 
9
16
  RSpec.configure do |config|
@@ -12,6 +19,7 @@ RSpec.configure do |config|
12
19
  Mifiel.config do |conf|
13
20
  conf.app_id = 'APP_ID'
14
21
  conf.app_secret = 'APP_SECRET'
22
+ conf.base_url = 'http://www.mifiel.com/api/v1'
15
23
  end
16
24
  end
17
25
 
@@ -1,6 +1,21 @@
1
1
  require 'sinatra/base'
2
2
 
3
3
  class FakeMifiel < Sinatra::Base
4
+ get '/api/v1/keys' do
5
+ content_type :json
6
+ status 200
7
+ [
8
+ key,
9
+ key
10
+ ].to_json
11
+ end
12
+
13
+ post '/api/v1/keys' do
14
+ content_type :json
15
+ status 200
16
+ key(id: params[:id]).to_json
17
+ end
18
+
4
19
  get '/api/v1/documents' do
5
20
  content_type :json
6
21
  status 200
@@ -30,8 +45,28 @@ class FakeMifiel < Sinatra::Base
30
45
  ).to_json
31
46
  end
32
47
 
48
+ post '/api/v1/documents/:id/request_signature' do
49
+ content_type :json
50
+ status 200
51
+ { bla: 'Correo enviado' }.to_json
52
+ end
53
+
33
54
  private
34
55
 
56
+ def key(args={})
57
+ id = args[:id] || SecureRandom.uuid
58
+ {
59
+ id: id,
60
+ type_of: 'FIEL',
61
+ cer_hex: '308204cf30...1303030303030323',
62
+ owner: 'JORGE MORALES MENDEZ',
63
+ tax_id: 'MOMJ811012643',
64
+ expires_at: '2017-04-28T19:43:23.000Z',
65
+ expired: false
66
+ }
67
+ end
68
+
69
+ # rubocop:disable Metrics/MethodLength
35
70
  def document(args={})
36
71
  id = args[:id] || SecureRandom.uuid
37
72
  {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mifiel
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Genaro Madrid
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-26 00:00:00.000000000 Z
11
+ date: 2016-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -228,6 +228,20 @@ dependencies:
228
228
  - - "~>"
229
229
  - !ruby/object:Gem::Version
230
230
  version: '0.36'
231
+ - !ruby/object:Gem::Dependency
232
+ name: simplecov
233
+ requirement: !ruby/object:Gem::Requirement
234
+ requirements:
235
+ - - "~>"
236
+ - !ruby/object:Gem::Version
237
+ version: '0.11'
238
+ type: :development
239
+ prerelease: false
240
+ version_requirements: !ruby/object:Gem::Requirement
241
+ requirements:
242
+ - - "~>"
243
+ - !ruby/object:Gem::Version
244
+ version: '0.11'
231
245
  description:
232
246
  email:
233
247
  - genmadrid@gmail.com
@@ -239,10 +253,9 @@ files:
239
253
  - ".gitignore"
240
254
  - ".rspec"
241
255
  - ".rubocop.yml"
242
- - ".ruby-gemset"
243
- - ".ruby-version"
244
256
  - ".travis.yml"
245
257
  - Gemfile
258
+ - Guardfile
246
259
  - LICENSE.txt
247
260
  - README.md
248
261
  - Rakefile
@@ -254,10 +267,13 @@ files:
254
267
  - lib/mifiel/document.rb
255
268
  - lib/mifiel/errors.rb
256
269
  - lib/mifiel/version.rb
270
+ - mifiel-ruby-api-client.sublime-project
257
271
  - mifiel.gemspec
258
272
  - spec/fixtures/FIEL_AAA010101AAA.cer
259
273
  - spec/fixtures/FIEL_AAA010101AAA.key
260
274
  - spec/fixtures/example.pdf
275
+ - spec/mifiel/base_spec.rb
276
+ - spec/mifiel/certificate_spec.rb
261
277
  - spec/mifiel/document_spec.rb
262
278
  - spec/spec_helper.rb
263
279
  - spec/support/fake_mifiel.rb
@@ -289,6 +305,8 @@ test_files:
289
305
  - spec/fixtures/FIEL_AAA010101AAA.cer
290
306
  - spec/fixtures/FIEL_AAA010101AAA.key
291
307
  - spec/fixtures/example.pdf
308
+ - spec/mifiel/base_spec.rb
309
+ - spec/mifiel/certificate_spec.rb
292
310
  - spec/mifiel/document_spec.rb
293
311
  - spec/spec_helper.rb
294
312
  - spec/support/fake_mifiel.rb
@@ -1 +0,0 @@
1
- mifiel_api_client
@@ -1 +0,0 @@
1
- 2.1.2