reg.api2 0.0.3 → 0.0.4

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.
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # REG.API 2 for Ruby
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/reg.api2.png)](http://badge.fury.io/rb/reg.api2)
3
4
  [![build status](https://secure.travis-ci.org/regru/reg_api2-ruby.png)](https://travis-ci.org/regru/reg_api2-ruby)
4
5
  [![Code Climate](https://codeclimate.com/github/regru/reg_api2-ruby.png)](https://codeclimate.com/github/regru/reg_api2-ruby)
5
6
  [![Coverage Status](https://coveralls.io/repos/regru/reg_api2-ruby/badge.png?branch=master)](https://coveralls.io/r/regru/reg_api2-ruby)
@@ -8,6 +9,8 @@ REG.API v2 Implementation.
8
9
 
9
10
  We want to note that Ruby client uses recommended way to access API: POST requests with JSON input/output in utf-8 encoding over HTTPS protocol.
10
11
 
12
+ This code hosted on [GitHub](https://github.com/regru/reg_api2-ruby).
13
+
11
14
  ## Installation
12
15
 
13
16
  Add this line to your application's Gemfile:
data/lib/reg_api2/impl.rb CHANGED
@@ -35,29 +35,40 @@ module RegApi2
35
35
  @description = description
36
36
  @params = params
37
37
  end
38
+
39
+ # Extracts error arguments from specified json.
40
+ # @param [Hash] json
41
+ # @return [ApiError] Initialized error object.
42
+ def self.from_json json
43
+ new(
44
+ json['error_code'],
45
+ json['error_text'],
46
+ json['error_params']
47
+ )
48
+ end
38
49
  end
39
50
 
40
51
  class << self
41
52
  # @!attribute [rw] username
42
- # @return [String] User name.
53
+ # @return [String] User name (`test` by default).
43
54
  attr_accessor :username
44
55
  # @!attribute [rw] password
45
- # @return [String] Password.
56
+ # @return [String] Password (`test` by default).
46
57
  attr_accessor :password
47
58
  # @!attribute [rw] io_encoding
48
- # @return [String] IO encoding ('utf-8' by default).
59
+ # @return [String] IO encoding (`utf-8` by default).
49
60
  attr_accessor :io_encoding
50
61
  # @!attribute [rw] lang
51
- # @return [String] Language ('en' by default).
62
+ # @return [String] Language (`en` by default).
52
63
  attr_accessor :lang
53
64
  # @!attribute [rw] ca_cert_path
54
- # @return [String] Path to certificate (nil by default).
65
+ # @return [String] Path to certification authority certificate (nil by default).
55
66
  attr_accessor :ca_cert_path
56
67
  # @!attribute [rw] pem
57
- # @return [String] PEM (nil by default).
68
+ # @return [String] X.509 certificate (nil by default).
58
69
  attr_accessor :pem
59
70
  # @!attribute [rw] pem_password
60
- # @return [String] PEM password (nil by default).
71
+ # @return [String] X.509 certificate password (nil by default).
61
72
  attr_accessor :pem_password
62
73
 
63
74
  # Default IO encoding
@@ -68,32 +79,59 @@ module RegApi2
68
79
  # REG.API base URI
69
80
  API_URI = URI.parse("https://api.reg.ru/api/regru2")
70
81
 
82
+ def apply_ca_cert_path(http)
83
+ unless ca_cert_path.nil?
84
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
85
+ http.ca_file = ca_cert_path
86
+ else
87
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
88
+ end
89
+ end
90
+
91
+ def apply_pem(http)
92
+ return if pem.nil?
93
+ http.cert = OpenSSL::X509::Certificate.new(pem)
94
+ if pem_password
95
+ raise ArgumentError, "The private key requires a password" if pem_password.empty?
96
+ http.key = OpenSSL::PKey::RSA.new(pem, pem_password)
97
+ else
98
+ http.key = OpenSSL::PKey::RSA.new(pem)
99
+ end
100
+ end
101
+
102
+ private :apply_pem, :apply_ca_cert_path
103
+
104
+ # Creates HTTPS handler.
105
+ # @return [Net::HTTP] HTTPS handler.
106
+ # @see #http
107
+ def create_http
108
+ _http = Net::HTTP.new(
109
+ API_URI.host,
110
+ API_URI.port
111
+ )
112
+ _http.use_ssl = true
113
+ apply_ca_cert_path(_http)
114
+ apply_pem(_http)
115
+ _http
116
+ end
117
+
71
118
  # Creates or gets HTTPS handler.
72
119
  # @return [Net::HTTP] HTTPS handler.
120
+ # @see #create_http
121
+ # @see #clear_http
73
122
  def http
74
- @http ||= begin
75
- http = Net::HTTP.new(
76
- API_URI.host,
77
- API_URI.port
78
- )
79
- http.use_ssl = true
80
- unless ca_cert_path.nil?
81
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
82
- http.ca_file = ca_cert_path
83
- else
84
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
85
- end
86
- unless pem.nil?
87
- http.cert = OpenSSL::X509::Certificate.new(pem)
88
- if pem_password
89
- raise ArgumentError, "The private key requires a password" if pem_password.empty?
90
- http.key = OpenSSL::PKey::RSA.new(pem, pem_password)
91
- else
92
- http.key = OpenSSL::PKey::RSA.new(pem)
93
- end
94
- end
95
- http
96
- end
123
+ @http ||= create_http
124
+ end
125
+
126
+ # Clears internal `http` singleton.
127
+ # Also finishes any started HTTP session.
128
+ # @return nil
129
+ # @note For testing purposes.
130
+ # @see #http
131
+ def clear_http
132
+ return nil unless @http
133
+ @http.finish if @http.respond_to?(:started) && @http.started
134
+ @http = nil
97
135
  end
98
136
 
99
137
  # Placeholder to inspect sent form
@@ -118,20 +156,20 @@ module RegApi2
118
156
  # HACK: REG.API doesn't know about utf-8.
119
157
  io_encoding = 'utf8' if !io_encoding || io_encoding == DEFAULT_IO_ENCODING
120
158
  opts = opts.to_hash if opts.respond_to?(:to_hash)
121
- opts = RegApi2::RequestContract.new(defopts).validate(opts)
159
+ req_contract = RegApi2::RequestContract.new(defopts)
160
+ opts = req_contract.validate(opts)
122
161
 
123
162
  form = {
124
- 'io_encoding' => io_encoding,
125
- 'lang' => lang || DEFAULT_LANG,
126
- 'output_format' => 'json',
127
- 'input_format' => 'json',
163
+ 'username' => username || 'test',
164
+ 'password' => password || 'test',
165
+ 'io_encoding' => io_encoding,
166
+ 'lang' => lang || DEFAULT_LANG,
167
+ 'output_format' => 'json',
168
+ 'input_format' => 'json',
128
169
  'show_input_params' => 0,
129
- 'input_data' => Yajl::Encoder.encode(opts)
170
+ 'input_data' => Yajl::Encoder.encode(opts)
130
171
  }
131
172
 
132
- form['username'] = username if username
133
- form['password'] = password if password
134
-
135
173
  form
136
174
  end
137
175
 
@@ -146,11 +184,7 @@ module RegApi2
146
184
  raise NetError.new(res.body) unless res.code == '200'
147
185
 
148
186
  json = Yajl::Parser.parse(res.body)
149
- raise ApiError.new(
150
- json['error_code'],
151
- json['error_text'],
152
- json['error_params']
153
- ) if json['result'] == 'error'
187
+ raise ApiError.from_json(json) if json['result'] == 'error'
154
188
 
155
189
  res_contract = RegApi2::ResultContract.new(defopts)
156
190
  res_contract.handle_result(json)
@@ -1,5 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module RegApi2
3
3
  # Gem version.
4
- VERSION = "0.0.3".freeze
4
+ VERSION = "0.0.4".freeze
5
5
  end
data/lib/reg_api2.rb CHANGED
@@ -33,6 +33,7 @@ require 'reg_api2/zone'
33
33
  # * {RegApi2.password} - Your password. `test` by default.
34
34
  # * {RegApi2.io_encoding} - Input/ouput encoding. `utf-8` by default.
35
35
  # * {RegApi2.lang} - Language of API answers. `en` by default.
36
+ # * {RegApi2.ca_cert_path}, {RegApi2.pem} and {RegApi2.pem_password} - optional certification properties. nils by default.
36
37
  #
37
38
  # Provides shortcuts for API categories:
38
39
  #
data/reg.api2.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["akzhan.abdulin@gmail.com"]
11
11
  spec.description = %q{REG.API v2 Implementation}
12
12
  spec.summary = %q{REG.API v2 Implementation}
13
- spec.homepage = "https://github.com/regru/reg_api2-ruby"
13
+ spec.homepage = "https://regru.github.com/reg_api2-ruby"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
@@ -0,0 +1,82 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ describe RegApi2 do
4
+ describe :http do
5
+ before(:each) do
6
+ RegApi2.clear_http
7
+ end
8
+
9
+ after(:all) do
10
+ RegApi2.clear_http
11
+ end
12
+
13
+ it "should #create_http at first call" do
14
+ mock(RegApi2).create_http { 45 }.times(1)
15
+ RegApi2.http.should == 45
16
+ end
17
+
18
+ it "should not #create_http at next call" do
19
+ mock(RegApi2).create_http { 45 }.times(1)
20
+ RegApi2.http.should == 45
21
+ RegApi2.http.should == 45
22
+ end
23
+ end
24
+
25
+ describe :create_http do
26
+ it "should create Net::HTTP object" do
27
+ http = RegApi2.create_http
28
+ http.should be_kind_of(Net::HTTP)
29
+ http.should be_use_ssl
30
+ http.verify_mode.should == OpenSSL::SSL::VERIFY_NONE
31
+ end
32
+
33
+ it "should use ca_cert_path if exists" do
34
+ any_instance_of(Net::HTTP) do |instance|
35
+ proxy(instance).verify_mode=(OpenSSL::SSL::VERIFY_PEER)
36
+ proxy(instance).ca_file=("file")
37
+ end
38
+ mock(RegApi2).ca_cert_path { "file" }.any_times
39
+ http = RegApi2.create_http
40
+ http.verify_mode.should == OpenSSL::SSL::VERIFY_PEER
41
+ http.ca_file.should == "file"
42
+ end
43
+
44
+ it "should use pem with pem_password" do
45
+ mock(RegApi2).pem { "pem" }.any_times
46
+ mock(RegApi2).pem_password { "pem_password" }.any_times
47
+ pem = Object.new
48
+ key = Object.new
49
+ mock(OpenSSL::X509::Certificate).new("pem") { pem }
50
+ mock(OpenSSL::PKey::RSA).new("pem", "pem_password") { key }
51
+
52
+ http = RegApi2.create_http
53
+ http.cert.should == pem
54
+ http.key.should == key
55
+ end
56
+
57
+ it "should use pem without pem_password" do
58
+ mock(RegApi2).pem { "pem" }.any_times
59
+ mock(RegApi2).pem_password { nil }.any_times
60
+ pem = Object.new
61
+ key = Object.new
62
+ mock(OpenSSL::X509::Certificate).new("pem") { pem }
63
+ mock(OpenSSL::PKey::RSA).new("pem") { key }
64
+
65
+ http = RegApi2.create_http
66
+ http.cert.should == pem
67
+ http.key.should_not be_nil
68
+ end
69
+ end
70
+
71
+ describe :make_action do
72
+
73
+ it "should raise ApiError with NO_SUCH_COMMAND code on absent command" do
74
+ lambda do
75
+ RegApi2.make_action(:bad, :command, {}, {})
76
+ end.should raise_error RegApi2::ApiError
77
+ lambda do
78
+ RegApi2.make_action(:bad, :command, {}, {})
79
+ end.should raise_error /NO_SUCH_COMMAND/
80
+ end
81
+ end
82
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reg.api2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -230,6 +230,7 @@ files:
230
230
  - spec/lib/reg_api2/domain_spec.rb
231
231
  - spec/lib/reg_api2/entity/entity_base_spec.rb
232
232
  - spec/lib/reg_api2/folder_spec.rb
233
+ - spec/lib/reg_api2/impl_spec.rb
233
234
  - spec/lib/reg_api2/request_contract_spec.rb
234
235
  - spec/lib/reg_api2/result_contract_spec.rb
235
236
  - spec/lib/reg_api2/service_spec.rb
@@ -237,7 +238,7 @@ files:
237
238
  - spec/lib/reg_api2/user_spec.rb
238
239
  - spec/lib/reg_api2/zone_spec.rb
239
240
  - spec/spec_helper.rb
240
- homepage: https://github.com/regru/reg_api2-ruby
241
+ homepage: https://regru.github.com/reg_api2-ruby
241
242
  licenses:
242
243
  - MIT
243
244
  post_install_message:
@@ -252,7 +253,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
252
253
  version: '0'
253
254
  segments:
254
255
  - 0
255
- hash: -2651933620898145662
256
+ hash: 784159006101606174
256
257
  required_rubygems_version: !ruby/object:Gem::Requirement
257
258
  none: false
258
259
  requirements:
@@ -261,7 +262,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
261
262
  version: '0'
262
263
  segments:
263
264
  - 0
264
- hash: -2651933620898145662
265
+ hash: 784159006101606174
265
266
  requirements: []
266
267
  rubyforge_project:
267
268
  rubygems_version: 1.8.24
@@ -275,6 +276,7 @@ test_files:
275
276
  - spec/lib/reg_api2/domain_spec.rb
276
277
  - spec/lib/reg_api2/entity/entity_base_spec.rb
277
278
  - spec/lib/reg_api2/folder_spec.rb
279
+ - spec/lib/reg_api2/impl_spec.rb
278
280
  - spec/lib/reg_api2/request_contract_spec.rb
279
281
  - spec/lib/reg_api2/result_contract_spec.rb
280
282
  - spec/lib/reg_api2/service_spec.rb