bnet-authenticator 0.1.1 → 0.1.2

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: 365b40fb792dd5b40f624f03a201736bf0d6222d
4
- data.tar.gz: c2ca91aa7707d402b6d162877b9617c13ed14585
3
+ metadata.gz: a7056e70c2b6c9ef1287b439f7fdc4af94f7d12c
4
+ data.tar.gz: ea57bd0c4df97f40c4d5b28176388c5401f62f4f
5
5
  SHA512:
6
- metadata.gz: cd923341d7be293c46ebc458a709377fd3922fe387a2199db6c049cb7e08b7361923b032fdc71510967dde0fdcab860702196e48315b7387038dfb45e05f4eb7
7
- data.tar.gz: 45e7208d2a4886676db024ae730093e0de9edc0e236ca9fdc3c899f3098bbb0db7163a8090abd0b4d2041cb0d1baa1523cb111d7185101344f6f395ab7b779df
6
+ metadata.gz: 25eb9dbf2d68c0367ef0a9166c0e7633ba0cf7b51bfa5e972f0288ff1f694ed3badfc70a63153c487d64666fbad325297e54686bd6a23efd434f6cd3f42834c8
7
+ data.tar.gz: 9ba3f92663b958d3990dd161cf2d5563c3262d1a0c15831bd0ebc92b4fe2d08aa074be473efb44e907c1e557fc2f01b8f4fcd73ff34bd531cc89270ef67bbbdf
data/README.md CHANGED
@@ -4,7 +4,7 @@ Ruby implementation of the Battle.net Mobile Authenticator.
4
4
 
5
5
  [![Gem Version](https://badge.fury.io/rb/bnet-authenticator.png)](http://badge.fury.io/rb/bnet-authenticator)
6
6
 
7
- [![Build Status](https://travis-ci.org/dorentus/bnet-authenticator.png?branch=master)](https://travis-ci.org/dorentus/bnet-authenticator) [![Dependency Status](https://gemnasium.com/dorentus/bnet-authenticator.png)](https://gemnasium.com/dorentus/bnet-authenticator) [![Coverage Status](https://coveralls.io/repos/dorentus/bnet-authenticator/badge.png)](https://coveralls.io/r/dorentus/bnet-authenticator)
7
+ [![Build Status](https://travis-ci.org/dorentus/bnet-authenticator.png?branch=master)](https://travis-ci.org/dorentus/bnet-authenticator) [![Dependency Status](https://gemnasium.com/dorentus/bnet-authenticator.png)](https://gemnasium.com/dorentus/bnet-authenticator) [![Coverage Status](https://coveralls.io/repos/dorentus/bnet-authenticator/badge.png)](https://coveralls.io/r/dorentus/bnet-authenticator) [![Code Climate](https://codeclimate.com/github/dorentus/bnet-authenticator.png)](https://codeclimate.com/github/dorentus/bnet-authenticator)
8
8
 
9
9
  Installation
10
10
  ====
@@ -17,8 +17,9 @@ Gem::Specification.new do |s|
17
17
  s.required_ruby_version = '>= 1.9.3'
18
18
 
19
19
  if s.respond_to?(:add_development_dependency)
20
- s.add_development_dependency 'rake', '~> 0'
21
- s.add_development_dependency 'yard', '~> 0'
20
+ s.add_development_dependency 'rake', '~> 10.1'
21
+ s.add_development_dependency 'minitest', '~> 5.0'
22
+ s.add_development_dependency 'yard', '~> 0.8'
22
23
  s.add_development_dependency 'coveralls', '~> 0.7'
23
24
  end
24
25
 
@@ -2,7 +2,7 @@ require 'bnet/authenticator/core'
2
2
 
3
3
  module Bnet
4
4
 
5
- # The battlenet authenticator
5
+ # The battle.net authenticator
6
6
  class Authenticator
7
7
 
8
8
  # @!attribute [r] serial
@@ -13,7 +13,7 @@ module Bnet
13
13
  # @return [String] hexified secret of the authenticator
14
14
  attr_reader :secret
15
15
 
16
- # @!attribute [r] restoration code
16
+ # @!attribute [r] restorecode
17
17
  # @return [String] the restoration code of the authenticator
18
18
  attr_reader :restorecode
19
19
 
@@ -21,37 +21,28 @@ module Bnet
21
21
  # @return [Symbol] the region of the authenticator
22
22
  attr_reader :region
23
23
 
24
- # Get a new authenticator
24
+ # Create a new authenticator object
25
+ # @param options [Hash] read the examples for more infomation
25
26
  #
26
- # == Example:
27
+ # == Examples:
28
+ # >> # Create an authenticator object with given serial and secret
27
29
  # >> Bnet::Authenticator.new(:serial => 'CN-1402-1943-1283', :secret => '4202aa2182640745d8a807e0fe7e34b30c1edb23')
28
30
  # => Serial: CN-1402-1943-1283
29
31
  # Secret: 4202aa2182640745d8a807e0fe7e34b30c1edb23
30
32
  # Restoration Code: 4CKBN08QEB
31
33
  #
34
+ # >> # Request server for a new authenticator
32
35
  # >> Bnet::Authenticator.new(:region => :US)
33
36
  # => Serial: US-1402-2552-9200
34
37
  # Secret: c1307afe865735653d981771dff04ceb79b1a353
35
38
  # Restoration Code: EQXCPB2YVE
36
39
  #
40
+ # >> # Reqeust to restore an authenticator
37
41
  # >> Bnet::Authenticator.new(:serial => 'CN-1402-1943-1283', :restorecode => '4CKBN08QEB')
38
42
  # => Serial: CN-1402-1943-1283
39
43
  # Secret: 4202aa2182640745d8a807e0fe7e34b30c1edb23
40
44
  # Restoration Code: 4CKBN08QEB
41
45
  #
42
- # == Parameters:
43
- # options:
44
- # A Hash. Valid key combanations are:
45
- #
46
- # - :serial and :secret
47
- # Create a new authenticator with given serial and secret.
48
- #
49
- # - :region
50
- # Request for a new authenticator using given region.
51
- #
52
- # - :serial and :restorecode
53
- # Reqeust to restore an authenticator using given serial and restoration code.
54
- #
55
46
  def initialize(options = {})
56
47
  options = Core.normalize_options(options)
57
48
 
@@ -71,7 +62,7 @@ module Bnet
71
62
  def restorecode
72
63
  return nil if @serial.nil? or @secret.nil?
73
64
 
74
- code_bin = Digest::SHA1.digest(normalized_serial + binary_secret).reverse[0, 10].reverse
65
+ code_bin = Digest::SHA1.digest(Core.normalize_serial(@serial) + @secret.as_hex_to_bin).reverse[0, 10].reverse
75
66
  Core.encode_restorecode(code_bin)
76
67
  end
77
68
 
@@ -81,8 +72,8 @@ module Bnet
81
72
  Core.extract_region(@serial)
82
73
  end
83
74
 
84
- # Caculate token using this authenticator's `secret` and given `timestamp`
85
- # (defaults to current time)
75
+ # Caculate token using this authenticator's secret and given timestamp
76
+ # (in seconds, defaults to current timestamp)
86
77
  #
87
78
  # @param timestamp [Integer] a UNIX timestamp in seconds
88
79
  # @return [String] current token
@@ -90,8 +81,14 @@ module Bnet
90
81
  Core.caculate_token(@secret, timestamp)
91
82
  end
92
83
 
93
- # Caculate token using giving `secret` and given `timestamp`
94
- # (defaults to current time)
84
+ # String representation of this authenticator
85
+ # @return [String]
86
+ def to_s
87
+ "Serial: #{serial}\nSecret: #{secret}\nRestoration Code: #{restorecode}"
88
+ end
89
+
90
+ # Caculate token using given secret and timestamp
91
+ # (in seconds, defaults to current timestamp)
95
92
  #
96
93
  # @param secret [String] hexified secret string of an authenticator
97
94
  # @param timestamp [Integer] a UNIX timestamp in seconds
@@ -100,32 +97,14 @@ module Bnet
100
97
  Core.caculate_token(secret, timestamp)
101
98
  end
102
99
 
103
- # Request for server timestamp
100
+ # Get server's time
104
101
  #
105
102
  # @param region [Symbol]
106
- # @return [Integer] server timestamp
103
+ # @return [Integer] server timestamp in seconds
107
104
  def self.request_server_time(region)
108
105
  Core.request_server_time(region)
109
106
  end
110
107
 
111
- # String representation of this authenticator
112
- # @return [String]
113
- def to_s
114
- "Serial: #{serial}\nSecret: #{secret}\nRestoration Code: #{restorecode}"
115
- end
116
-
117
- private
118
-
119
- def normalized_serial
120
- Core.normalize_serial(@serial)
121
- end
122
-
123
- def binary_secret
124
- return nil if @secret.nil?
125
-
126
- @secret.as_hex_to_bin
127
- end
128
-
129
108
  end
130
109
 
131
110
  end
@@ -13,9 +13,9 @@ module Bnet
13
13
  RSA_MOD = 104890018807986556874007710914205443157030159668034197186125678960287470894290830530618284943118405110896322835449099433232093151168250152146023319326491587651685252774820340995950744075665455681760652136576493028733914892166700899109836291180881063097461175643998356321993663868233366705340758102567742483097
14
14
  RSA_KEY = 257
15
15
  AUTHENTICATOR_HOSTS = {
16
- :CN => "mobile-service.battlenet.com.cn",
17
- :EU => "m.eu.mobileservice.blizzard.com",
18
- :US => "m.us.mobileservice.blizzard.com",
16
+ :CN => "mobile-service.battlenet.com.cn",
17
+ :EU => "m.eu.mobileservice.blizzard.com",
18
+ :US => "m.us.mobileservice.blizzard.com",
19
19
  }
20
20
  ENROLLMENT_REQUEST_PATH = '/enrollment/enroll.htm'
21
21
  TIME_REQUEST_PATH = '/enrollment/time.htm'
@@ -37,135 +37,57 @@ module Bnet
37
37
  end
38
38
  RESTORECODE_MAP_INVERSE = RESTORECODE_MAP.invert
39
39
 
40
- def self.caculate_token(secret, timestamp = nil)
41
- secret = normalize_options(:secret => secret)[:secret]
42
- return nil if secret.nil?
43
-
44
- timestamp = Time.now.getutc.to_i if timestamp.nil?
45
-
46
- current = timestamp / 30
47
- next_timestamp = (current + 1) * 30
48
-
49
- digest = Digest::HMAC.digest([current].pack('Q>'), secret.as_hex_to_bin, Digest::SHA1)
50
-
51
- start_position = digest[19].ord & 0xf
52
-
53
- token = '%08d' % (digest[start_position, 4].as_bin_to_i % 100000000)
54
-
55
- return token, next_timestamp
56
- end
57
-
58
- def self.normalize_serial(serial)
59
- serial.to_s.gsub(/-/, '').upcase
60
- end
61
-
62
- def self.prettify_serial(serial)
63
- serial = normalize_serial(serial)
64
- "#{serial[0, 2]}-" + serial[2, 12].scan(/.{4}/).join('-')
65
- end
66
-
67
- private
68
-
69
40
  def self.normalize_options(options)
70
41
  return nil if options.nil?
71
42
 
72
- if options.has_key?(:serial)
73
- normalized_serial = normalize_serial(options[:serial])
74
- region = extract_region(normalized_serial)
75
-
76
- if AUTHENTICATOR_HOSTS.has_key?(region) && normalized_serial =~ /\d{12}/
77
- options[:serial] = prettify_serial(normalized_serial)
78
- else
79
- raise BadInputError.new("bad serial #{options[:serial]}")
43
+ %w(serial region restorecode secret).each do |attr|
44
+ if options.has_key? attr.to_sym
45
+ options[attr.to_sym] = send "normalize_#{attr}".to_sym, options[attr.to_sym] do |value|
46
+ raise BadInputError.new("bad #{attr} #{value}")
47
+ end
80
48
  end
81
49
  end
82
50
 
83
- if options.has_key?(:region)
84
- region = options[:region].to_s.upcase.to_sym
85
- raise BadInputError.new("unsupported region #{region}") unless AUTHENTICATOR_HOSTS.has_key?(region)
86
-
87
- options[:region] = region
88
- end
89
-
90
- if options.has_key?(:restorecode)
91
- restorecode = options[:restorecode].upcase
92
-
93
- raise BadInputError.new("bad restoration code #{restorecode}") unless restorecode =~ /[0-9A-Z]{10}/
94
-
95
- options[:restorecode] = restorecode
96
- end
97
-
98
- if options.has_key?(:secret)
99
- secret = options[:secret]
100
- raise BadInputError.new("bad secret #{secret}") unless secret =~ /[0-9a-f]{40}/i
101
- end
51
+ options[:serial] = prettify_serial(options[:serial]) if options.has_key?(:serial)
102
52
 
103
53
  options
104
54
  end
105
55
 
106
- def self.extract_region(serial)
107
- serial.to_s[0, 2].upcase.to_sym
108
- end
109
-
110
- def self.create_one_time_pad(length)
111
- (0..1.0/0.0).reduce('') do |memo, i|
112
- break memo if memo.length >= length
113
- memo << Digest::SHA1.digest(rand().to_s)
114
- end[0, length]
115
- end
116
-
117
56
  def self.encode_restorecode(bin)
118
57
  bin.bytes.map do |v|
119
58
  RESTORECODE_MAP[v & 0x1f]
120
59
  end.as_bytes_to_bin
121
60
  end
122
61
 
123
- def self.decode_restorecode(str)
124
- str.bytes.map do |c|
125
- RESTORECODE_MAP_INVERSE[c]
126
- end.as_bytes_to_bin
62
+ def self.extract_region(serial)
63
+ serial.to_s[0, 2].upcase.to_sym
127
64
  end
128
65
 
129
- def self.request_new_serial(region, model = nil)
130
- model ||= 'bn/authenticator'
66
+ def self.caculate_token(secret, timestamp = nil)
67
+ secret = normalize_secret secret do |invalid_secret|
68
+ return nil
69
+ end
131
70
 
132
- # one-time key of 37 bytes
133
- k = create_one_time_pad(37)
71
+ current = (timestamp || Time.now.getutc.to_i) / 30
134
72
 
135
- # make byte[56]
136
- # 00 byte[1] 固定为1
137
- # 01 byte[37] 37位的随机数据,只使用一次,用来解密服务器返回数据
138
- # 38 byte[2] 区域码: CN, US, EU, etc.
139
- # 40 byte[16] 设备模型数据(手机型号字符串,可随意)
140
- bytes = [1]
141
- bytes.concat(k.bytes.to_a)
142
- bytes.concat(region.to_s.bytes.take(2))
143
- bytes.concat(model.ljust(16, "\0").bytes.take(16))
73
+ digest = Digest::HMAC.digest([current].pack('Q>'), secret.as_hex_to_bin, Digest::SHA1)
144
74
 
145
- # encrypted using RSA
146
- e = (bytes.as_bytes_to_i ** RSA_KEY % RSA_MOD).to_bin
75
+ start_position = digest[19].ord & 0xf
147
76
 
148
- # request to server
149
- request = Net::HTTP::Post.new(ENROLLMENT_REQUEST_PATH)
150
- request.content_type = 'application/octet-stream'
151
- request.body = e
77
+ token = '%08d' % (digest[start_position, 4].as_bin_to_i % 100000000)
152
78
 
153
- response = Net::HTTP.new(AUTHENTICATOR_HOSTS[region]).start do |http|
154
- http.request(request)
155
- end
79
+ return token, (current + 1) * 30
80
+ end
156
81
 
157
- # server error
158
- # note: server is unhappy with certain `k`s, such as:
159
- # [206, 166, 17, 196, 68, 160, 142, 111, 216, 196, 170, 19, 49, 239, 101, 93, 114, 241, 57, 223, 150, 80, 219, 114, 95, 20, 42, 142, 193, 115, 79, 71, 189, 147, 242, 111, 27].as_bytes_to_bin
160
- raise RequestFailedError.new("Error requesting for new serial: #{response.code}") if response.code.to_i(10) != 200
82
+ def self.request_new_serial(region, model = nil)
83
+ e, k = prepair_serial_request(region, model || 'bn/authenticator')
161
84
 
162
- # the first 8 bytes be server timestamp in milliseconds
163
- # server_timestamp_in_ms = response.body[0, 8].as_bin_to_i
85
+ # request to server
86
+ response_body = request_for('new serial', region, ENROLLMENT_REQUEST_PATH, e)
164
87
 
88
+ # the first 8 bytes be server timestamp in milliseconds
165
89
  # the rest 37 bytes, to be XORed with `k`
166
- decrypted = response.body[8, 37].bytes.zip(k.bytes).reduce('') do |memo, pair|
167
- memo << (pair[0] ^ pair[1]).chr
168
- end
90
+ decrypted = decrypt_response(response_body[8, 37], k)
169
91
 
170
92
  # now
171
93
  # the first 20 bytes be the authenticator secret
@@ -182,56 +104,133 @@ module Bnet
182
104
  restorecode_bin = decode_restorecode(restorecode)
183
105
 
184
106
  # stage 1
185
- request = Net::HTTP::Post.new(RESTORE_INIT_REQUEST_PATH)
186
- request.content_type = 'application/octet-stream'
187
- request.body = serial_normalized
188
-
189
- response = Net::HTTP.new(AUTHENTICATOR_HOSTS[region]).start do |http|
190
- http.request(request)
191
- end
192
-
193
- raise RequestFailedError.new("Error requesting for restore (stage 1): #{response.code}") if response.code.to_i(10) != 200
107
+ challenge = request_for('restore (stage 1)', region, RESTORE_INIT_REQUEST_PATH, serial_normalized)
194
108
 
195
109
  # stage 2
196
- challenge = response.body
197
-
198
110
  key = create_one_time_pad(20)
199
111
 
200
112
  digest = Digest::HMAC.digest(serial_normalized + challenge,
201
113
  restorecode_bin,
202
114
  Digest::SHA1)
203
115
 
204
- payload = serial_normalized
205
- payload += ((digest+key).as_bin_to_i ** RSA_KEY % RSA_MOD).to_bin
206
-
207
- request = Net::HTTP::Post.new(RESTORE_VALIDATE_REQUEST_PATH)
208
- request.content_type = 'application/octet-stream'
209
- request.body = payload
210
-
211
- response = Net::HTTP.new(AUTHENTICATOR_HOSTS[region]).start do |http|
212
- http.request(request)
213
- end
116
+ payload = serial_normalized + rsa_encrypted((digest + key).as_bin_to_i)
214
117
 
215
- raise RequestFailedError.new("Error requesting for restore (stage 2): #{response.code}") if response.code.to_i(10) != 200
118
+ response_body = request_for('restore (stage 2)', region, RESTORE_VALIDATE_REQUEST_PATH, payload)
216
119
 
217
- secret = response.body.bytes.zip(key.bytes).reduce('') do |memo, pair|
218
- memo << (pair[0] ^ pair[1]).chr
219
- end.as_bin_to_hex
120
+ secret = decrypt_response(response_body, key).as_bin_to_hex
220
121
 
221
122
  return prettify_serial(serial), secret
222
123
  end
223
124
 
224
125
  def self.request_server_time(region)
225
- request = Net::HTTP::Get.new(TIME_REQUEST_PATH)
226
- request.content_type = 'application/octet-stream'
126
+ request_for('server time', region, TIME_REQUEST_PATH).as_bin_to_i.to_f / 1000
127
+ end
128
+
129
+ class << self
130
+
131
+ def normalize_serial(serial)
132
+ s = serial.to_s.gsub(/-/, '').upcase
133
+
134
+ if block_given?
135
+ region = extract_region(s)
136
+ yield serial unless (AUTHENTICATOR_HOSTS.has_key?(region) && s =~ /\d{12}/)
137
+ end
138
+
139
+ s
140
+ end
141
+
142
+ def prettify_serial(serial)
143
+ serial = normalize_serial(serial) { |bad_serial| return nil }
144
+ "#{serial[0, 2]}-" + serial[2, 12].scan(/.{4}/).join('-')
145
+ end
146
+
147
+ def normalize_region(region)
148
+ normalized_region = region.to_s.upcase.to_sym
149
+
150
+ if block_given? && !AUTHENTICATOR_HOSTS.has_key?(normalized_region)
151
+ yield region
152
+ end
153
+
154
+ normalized_region
155
+ end
156
+
157
+ def normalize_restorecode(restorecode)
158
+ restorecode = restorecode.upcase
159
+
160
+ if block_given? && !(restorecode =~ /[0-9A-Z]{10}/)
161
+ yield restorecode
162
+ end
227
163
 
228
- response = Net::HTTP.new(AUTHENTICATOR_HOSTS[region]).start do |http|
229
- http.request(request)
164
+ restorecode
230
165
  end
231
166
 
232
- raise RequestFailedError.new("Error requesting server time: #{response.code}") if response.code.to_i(10) != 200
167
+ def normalize_secret(secret)
168
+ if block_given? && !(secret =~ /[0-9a-f]{40}/i)
169
+ yield secret
170
+ end
171
+
172
+ secret
173
+ end
174
+
175
+ def create_one_time_pad(length)
176
+ (0..1.0/0.0).reduce('') do |memo, i|
177
+ break memo if memo.length >= length
178
+ memo << Digest::SHA1.digest(rand().to_s)
179
+ end[0, length]
180
+ end
181
+
182
+ def decode_restorecode(str)
183
+ str.bytes.map do |c|
184
+ RESTORECODE_MAP_INVERSE[c]
185
+ end.as_bytes_to_bin
186
+ end
187
+
188
+ def decrypt_response(text, key)
189
+ text.bytes.zip(key.bytes).reduce('') do |memo, pair|
190
+ memo + (pair[0] ^ pair[1]).chr
191
+ end
192
+ end
193
+
194
+ def rsa_encrypted(integer)
195
+ (integer ** RSA_KEY % RSA_MOD).to_bin
196
+ end
197
+
198
+ def prepair_serial_request(region, model)
199
+ # one-time key of 37 bytes
200
+ k = create_one_time_pad(37)
201
+
202
+ # make byte[56]
203
+ # 00 byte[1] 固定为1
204
+ # 01 byte[37] 37位的随机数据,只使用一次,用来解密服务器返回数据
205
+ # 38 byte[2] 区域码: CN, US, EU, etc.
206
+ # 40 byte[16] 设备模型数据(手机型号字符串,可随意)
207
+ bytes = [1]
208
+ bytes.concat(k.bytes.to_a)
209
+ bytes.concat(region.to_s.bytes.take(2))
210
+ bytes.concat(model.ljust(16, "\0").bytes.take(16))
211
+
212
+ # encrypted using RSA
213
+ e = rsa_encrypted(bytes.as_bytes_to_i)
214
+
215
+ return e, k
216
+ end
217
+
218
+ def request_for(label, region, path, body = nil)
219
+ request = body.nil? ? Net::HTTP::Get.new(path) : Net::HTTP::Post.new(path)
220
+ request.content_type = 'application/octet-stream'
221
+ request.body = body unless body.nil?
222
+
223
+ response = Net::HTTP.new(AUTHENTICATOR_HOSTS[region]).start do |http|
224
+ http.request request
225
+ end
226
+
227
+ if response.code.to_i != 200
228
+ raise RequestFailedError.new("Error requesting #{label}: #{response.code}")
229
+ end
230
+
231
+ response.body
232
+ end
233
233
 
234
- response.body.as_bin_to_i.to_f / 1000.0
235
234
  end
236
235
 
237
236
  end
@@ -1,5 +1,5 @@
1
1
  module Bnet
2
2
  class Authenticator
3
- VERSION = "0.1.1"
3
+ VERSION = "0.1.2"
4
4
  end
5
5
  end
@@ -1,10 +1,11 @@
1
1
  require 'coveralls'
2
2
  Coveralls.wear_merged!
3
3
 
4
- require 'test/unit'
4
+ gem "minitest"
5
+ require 'minitest/autorun'
5
6
  require 'bnet/authenticator'
6
7
 
7
- class Bnet::AuthenticatorTest < Test::Unit::TestCase
8
+ class Bnet::AuthenticatorTest < Minitest::Test
8
9
  DEFAULT_SERIAL = 'CN-1402-1943-1283'
9
10
  DEFAULT_SECRET = '4202aa2182640745d8a807e0fe7e34b30c1edb23'
10
11
  DEFAULT_RSCODE = '4CKBN08QEB'
@@ -16,19 +17,19 @@ class Bnet::AuthenticatorTest < Test::Unit::TestCase
16
17
  end
17
18
 
18
19
  def test_argument_error
19
- assert_raise ::Bnet::Authenticator::BadInputError do
20
+ assert_raises ::Bnet::Authenticator::BadInputError do
20
21
  Bnet::Authenticator.new
21
22
  end
22
23
 
23
- assert_raise ::Bnet::Authenticator::BadInputError do
24
+ assert_raises ::Bnet::Authenticator::BadInputError do
24
25
  Bnet::Authenticator.new(:serial => 'ABC')
25
26
  end
26
27
 
27
- assert_raise ::Bnet::Authenticator::BadInputError do
28
+ assert_raises ::Bnet::Authenticator::BadInputError do
28
29
  Bnet::Authenticator.new(:region => 'SG')
29
30
  end
30
31
 
31
- assert_raise ::Bnet::Authenticator::BadInputError do
32
+ assert_raises ::Bnet::Authenticator::BadInputError do
32
33
  Bnet::Authenticator.new(:restorecode => 'DDDD')
33
34
  end
34
35
  end
@@ -37,10 +38,11 @@ class Bnet::AuthenticatorTest < Test::Unit::TestCase
37
38
  begin
38
39
  authenticator = Bnet::Authenticator.new(:region => :US)
39
40
  assert_equal :US, authenticator.region
40
- assert_not_nil authenticator.serial
41
- assert_not_nil authenticator.secret
42
- assert_not_nil authenticator.restorecode
43
- rescue Bnet::Authenticator::RequestFailedError
41
+ refute_nil authenticator.serial
42
+ refute_nil authenticator.secret
43
+ refute_nil authenticator.restorecode
44
+ rescue Bnet::Authenticator::RequestFailedError => e
45
+ puts e
44
46
  end
45
47
  end
46
48
 
@@ -48,14 +50,16 @@ class Bnet::AuthenticatorTest < Test::Unit::TestCase
48
50
  begin
49
51
  authenticator = Bnet::Authenticator.new(:serial => DEFAULT_SERIAL, :restorecode => DEFAULT_RSCODE)
50
52
  is_default_authenticator authenticator
51
- rescue Bnet::Authenticator::RequestFailedError
53
+ rescue Bnet::Authenticator::RequestFailedError => e
54
+ puts e
52
55
  end
53
56
  end
54
57
 
55
58
  def test_request_server_time
56
59
  begin
57
60
  Bnet::Authenticator.request_server_time :EU
58
- rescue Bnet::Authenticator::RequestFailedError
61
+ rescue Bnet::Authenticator::RequestFailedError => e
62
+ puts e
59
63
  end
60
64
  end
61
65
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bnet-authenticator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - ZHANG Yi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-08 00:00:00.000000000 Z
11
+ date: 2014-03-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -16,28 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '10.1'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '10.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5.0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: yard
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: '0'
47
+ version: '0.8'
34
48
  type: :development
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
- version: '0'
54
+ version: '0.8'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: coveralls
43
57
  requirement: !ruby/object:Gem::Requirement