mifiel 1.0.3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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