registrar-client 0.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.
- data/LICENSE +19 -0
- data/Readme.md +70 -0
- data/Spec.md +55 -0
- data/examples/enom.example.yml +4 -0
- data/examples/purchase_com.rb +7 -0
- data/lib/registrar-client.rb +1 -0
- data/lib/registrar.rb +14 -0
- data/lib/registrar/client.rb +224 -0
- data/lib/registrar/contact.rb +31 -0
- data/lib/registrar/domain.rb +26 -0
- data/lib/registrar/extended_attribute.rb +12 -0
- data/lib/registrar/extended_attribute_descriptor.rb +31 -0
- data/lib/registrar/extended_attribute_option_descriptor.rb +7 -0
- data/lib/registrar/name_server.rb +16 -0
- data/lib/registrar/order.rb +43 -0
- data/lib/registrar/provider/enom.rb +430 -0
- data/lib/registrar/provider/enom/contact.rb +68 -0
- data/lib/registrar/provider/enom/extended_attribute.rb +64 -0
- data/lib/registrar/provider/enom/extended_attribute_be.rb +0 -0
- data/lib/registrar/provider/enom/extended_attribute_ca.rb +40 -0
- data/lib/registrar/provider/enom/extended_attribute_io.rb +18 -0
- data/lib/registrar/provider/enom/extended_attribute_us.rb +29 -0
- data/lib/registrar/provider/enom/order.rb +41 -0
- data/lib/registrar/provider/opensrs.rb +133 -0
- data/lib/registrar/provider/opensrs/contact.rb +30 -0
- data/lib/registrar/provider/opensrs/contact_set.rb +24 -0
- data/lib/registrar/provider/opensrs/name_server_list.rb +26 -0
- data/lib/registrar/provider/opensrs/operation.rb +42 -0
- data/lib/registrar/provider/opensrs/order.rb +59 -0
- data/lib/registrar/provider/opensrs/tld_data.rb +29 -0
- data/lib/registrar/provider/opensrs/tld_data_us.rb +48 -0
- data/lib/registrar/purchase_options.rb +29 -0
- data/lib/registrar/renewal_options.rb +8 -0
- metadata +177 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
module Registrar
|
2
|
+
class ExtendedAttributeDescriptor
|
3
|
+
attr_accessor :name
|
4
|
+
attr_accessor :description
|
5
|
+
attr_accessor :required
|
6
|
+
attr_accessor :child
|
7
|
+
attr_accessor :application
|
8
|
+
attr_accessor :user_defined
|
9
|
+
attr_accessor :options
|
10
|
+
attr_accessor :apply_to_registrar
|
11
|
+
|
12
|
+
alias :required? :required
|
13
|
+
alias :child? :child
|
14
|
+
alias :user_defined? :user_defined
|
15
|
+
alias :apply_to_registrar? :apply_to_registrar
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@options = []
|
19
|
+
end
|
20
|
+
|
21
|
+
def serializable_hash
|
22
|
+
{
|
23
|
+
'name' => name,
|
24
|
+
'description' => description,
|
25
|
+
'required' => required,
|
26
|
+
'options' => options
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Registrar #:nodoc:
|
2
|
+
# Instances of this class contain details about the current state of a
|
3
|
+
# particular order with the registrar.
|
4
|
+
class Order
|
5
|
+
# The service-specific identifier for the order.
|
6
|
+
attr_reader :identifier
|
7
|
+
|
8
|
+
# The current status of the order
|
9
|
+
attr_accessor :status
|
10
|
+
|
11
|
+
# The date the order was created
|
12
|
+
attr_accessor :date
|
13
|
+
|
14
|
+
# Construct a new Order instance.
|
15
|
+
def initialize(identifier)
|
16
|
+
@identifier = identifier
|
17
|
+
@status = :unknown
|
18
|
+
@successful = false
|
19
|
+
end
|
20
|
+
|
21
|
+
# Get the domains associated with this order
|
22
|
+
def domains
|
23
|
+
@domains ||= []
|
24
|
+
end
|
25
|
+
|
26
|
+
# Return true if the order is complete.
|
27
|
+
def complete?
|
28
|
+
![:open, :unknown].include?(@status)
|
29
|
+
end
|
30
|
+
|
31
|
+
def open?
|
32
|
+
@status == :open
|
33
|
+
end
|
34
|
+
|
35
|
+
def successful?
|
36
|
+
@successful
|
37
|
+
end
|
38
|
+
|
39
|
+
def successful=(successful)
|
40
|
+
@successful = successful
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,430 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'tzinfo'
|
3
|
+
|
4
|
+
require 'registrar/provider/enom/contact'
|
5
|
+
require 'registrar/provider/enom/extended_attribute'
|
6
|
+
require 'registrar/provider/enom/order'
|
7
|
+
|
8
|
+
module Registrar
|
9
|
+
module Provider
|
10
|
+
# Implementation of a registrar provider for Enom (http://www.enom.com/).
|
11
|
+
class Enom
|
12
|
+
include HTTParty
|
13
|
+
|
14
|
+
attr_accessor :url, :username, :password
|
15
|
+
|
16
|
+
def initialize(url, username, password)
|
17
|
+
@url = url
|
18
|
+
@username = username
|
19
|
+
@password = password
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse(name)
|
23
|
+
query = base_query.merge('Command' => 'ParseDomain')
|
24
|
+
response = execute(query.merge('PassedDomain' => name))
|
25
|
+
|
26
|
+
[response['ParseDomain']['SLD'], response['ParseDomain']['TLD']]
|
27
|
+
end
|
28
|
+
|
29
|
+
def available?(name)
|
30
|
+
sld, tld = parse(name)
|
31
|
+
|
32
|
+
query = base_query.merge('Command' => 'Check')
|
33
|
+
response = execute(query.merge('SLD' => sld, 'TLD' => tld))
|
34
|
+
|
35
|
+
response['RRPCode'] == '210'
|
36
|
+
end
|
37
|
+
|
38
|
+
def find(name)
|
39
|
+
sld, tld = parse(name)
|
40
|
+
query = base_query.merge('Command' => 'GetDomainInfo')
|
41
|
+
|
42
|
+
response = execute(query.merge('SLD' => sld, 'TLD' => tld))
|
43
|
+
|
44
|
+
domain = Registrar::Domain.new(name)
|
45
|
+
domain.expiration = response['GetDomainInfo']['status']['expiration']
|
46
|
+
domain.registration_status = response['GetDomainInfo']['status']['registrationstatus']
|
47
|
+
domain.order = order_for_domain(name)
|
48
|
+
domain
|
49
|
+
end
|
50
|
+
|
51
|
+
def purchase(name, registrant, purchase_options=nil)
|
52
|
+
purchase_options ||= Registrar::PurchaseOptions.new
|
53
|
+
|
54
|
+
sld, tld = parse(name)
|
55
|
+
query = base_query.merge('Command' => 'Purchase', 'SLD' => sld, 'TLD' => tld)
|
56
|
+
registrant = Enom::Contact.new(registrant)
|
57
|
+
|
58
|
+
if registrant
|
59
|
+
query.merge!(registrant.to_query("Registrant"))
|
60
|
+
query.merge!(registrant.to_query("AuxBilling"))
|
61
|
+
query.merge!(registrant.to_query("Tech"))
|
62
|
+
query.merge!(registrant.to_query("Admin"))
|
63
|
+
end
|
64
|
+
|
65
|
+
if purchase_options.has_name_servers?
|
66
|
+
query['IgnoreNSFail'] = 'Yes'
|
67
|
+
purchase_options.name_servers.each_with_index do |name_server, i|
|
68
|
+
case name_server
|
69
|
+
when String
|
70
|
+
query["NS#{i+1}"] = name_server
|
71
|
+
else
|
72
|
+
query["NS#{i+1}"] = name_server.name
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
else
|
77
|
+
query['UseDNS'] = 'default'
|
78
|
+
end
|
79
|
+
|
80
|
+
if purchase_options.has_extended_attributes?
|
81
|
+
extended_attributes = purchase_options.extended_attributes.map { |a| Enom::ExtendedAttribute.new(a) }
|
82
|
+
extended_attributes.each do |extended_attribute|
|
83
|
+
query[extended_attribute.name] = extended_attribute.value
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
query['NumYears'] = purchase_options.number_of_years || minimum_number_of_years(tld)
|
88
|
+
query['IDNCode'] = purchase_options.language if purchase_options.language
|
89
|
+
|
90
|
+
response = execute(query)
|
91
|
+
|
92
|
+
registrant.identifier = response['RegistrantPartyID']
|
93
|
+
|
94
|
+
domain = Registrar::Domain.new(name)
|
95
|
+
domain.registrant = registrant
|
96
|
+
domain.lockable = response['IsLockable'].downcase == 'true'
|
97
|
+
domain.real_time = response['IsRealTimeTLD'].downcase == 'true'
|
98
|
+
order = order(response['OrderID'])
|
99
|
+
order.domains << domain
|
100
|
+
domain.order = order
|
101
|
+
order
|
102
|
+
end
|
103
|
+
|
104
|
+
def renew(name, renewal_options=nil)
|
105
|
+
renewal_options ||= Registrar::RenewalOptions.new
|
106
|
+
sld, tld = parse(name)
|
107
|
+
query = base_query.merge('Command' => 'Extend', 'SLD' => sld, 'TLD' => tld)
|
108
|
+
query = query.merge('NumYears' => renewal_options.number_of_years)
|
109
|
+
response = execute(query)
|
110
|
+
response['Extension'] && response['Extension'].downcase == 'successful'
|
111
|
+
end
|
112
|
+
|
113
|
+
def auto_renew?(name)
|
114
|
+
sld, tld = parse(name)
|
115
|
+
query = base_query.merge('Command' => 'GetRenew', 'TLD' => tld, 'SLD' => sld)
|
116
|
+
response = execute_command(query)
|
117
|
+
response['auto_renew'] == '1'
|
118
|
+
end
|
119
|
+
|
120
|
+
def enable_auto_renewal(name)
|
121
|
+
sld, tld = parse(name)
|
122
|
+
query = base_query.merge('Command' => 'SetRenew', 'TLD' => tld, 'SLD' => sld)
|
123
|
+
query = query.merge('RenewFlag' => '1')
|
124
|
+
response = execute_command(query)
|
125
|
+
response['RenewName'] == 'True'
|
126
|
+
end
|
127
|
+
|
128
|
+
def disable_auto_renewal(name)
|
129
|
+
sld, tld = parse(name)
|
130
|
+
query = base_query.merge('Command' => 'SetRenew', 'TLD' => tld, 'SLD' => sld)
|
131
|
+
query = query.merge('RenewFlag' => '0')
|
132
|
+
response = execute_command(query)
|
133
|
+
response['RenewName'] == 'False'
|
134
|
+
end
|
135
|
+
|
136
|
+
def order(id)
|
137
|
+
query = base_query.merge('Command' => 'GetOrderDetail', 'OrderID' => id.to_s)
|
138
|
+
response = execute(query)
|
139
|
+
|
140
|
+
order = Enom::Order.new(response['Order']['OrderID'])
|
141
|
+
order.order_date = response['Order']['OrderDate']
|
142
|
+
order.order_status = response['Order']['OrderDetail']['OrderStatus']
|
143
|
+
order.status = response['Order']['OrderDetail']['Status']
|
144
|
+
order.to_order
|
145
|
+
end
|
146
|
+
|
147
|
+
def order_for_domain(name)
|
148
|
+
sld, tld = parse(name)
|
149
|
+
query = base_query.merge('Command' => 'GetDomainStatus', 'SLD' => sld, 'TLD' => tld)
|
150
|
+
response = execute_command(query)
|
151
|
+
order(response['DomainStatus']['OrderID'])
|
152
|
+
end
|
153
|
+
|
154
|
+
def name_servers(name)
|
155
|
+
sld, tld = parse(name)
|
156
|
+
query = base_query.merge('Command' => 'GetDNS', 'TLD' => tld, 'SLD' => sld)
|
157
|
+
response = execute_command(query)
|
158
|
+
[response['dns']].flatten
|
159
|
+
end
|
160
|
+
alias :nameservers :name_servers
|
161
|
+
|
162
|
+
def set_name_servers(name, name_servers=[])
|
163
|
+
sld, tld = parse(name)
|
164
|
+
query = base_query.merge('Command' => 'ModifyNS', 'TLD' => tld, 'SLD' => sld)
|
165
|
+
|
166
|
+
name_server_hash = {}
|
167
|
+
if name_servers.length == 0
|
168
|
+
name_server_hash["NS1"] = ""
|
169
|
+
else
|
170
|
+
name_servers.each_with_index do |ns_name, index|
|
171
|
+
name_server_hash["NS#{index + 1}"] = ns_name
|
172
|
+
end
|
173
|
+
end
|
174
|
+
query = query.merge(name_server_hash)
|
175
|
+
|
176
|
+
response = execute_command(query)
|
177
|
+
|
178
|
+
name_servers
|
179
|
+
end
|
180
|
+
|
181
|
+
def find_name_server(name)
|
182
|
+
query = base_query.merge('Command' => 'CheckNSStatus', 'CheckNSName' => name)
|
183
|
+
response = execute_command(query)
|
184
|
+
|
185
|
+
if response['NsCheckSuccess'] == '1'
|
186
|
+
name_server = Registrar::NameServer.new(response['CheckNsStatus']['name'])
|
187
|
+
name_server.ip_address = response['CheckNsStatus']['ipaddress']
|
188
|
+
name_server
|
189
|
+
else
|
190
|
+
raise RuntimeError, "Name server not found for #{name}"
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def register_name_server(name_server)
|
195
|
+
query = base_query.merge('Command' => 'RegisterNameServer', 'Add' => 'true', 'NSName' => name_server.name, 'IP' => name_server.ip_address)
|
196
|
+
response = execute_command(query)
|
197
|
+
|
198
|
+
if response['RRPCode'] == '200'
|
199
|
+
name_server = Registrar::NameServer.new(response['RegisterNameserver']['NS'])
|
200
|
+
name_server.ip_address = response['RegisterNameserver']['IP']
|
201
|
+
name_server
|
202
|
+
else
|
203
|
+
raise RuntimeError, "Unable to create name server: #{response['RRPText']}"
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def extended_attributes(name)
|
208
|
+
sld, tld = parse(name)
|
209
|
+
query = base_query.merge('Command' => 'GetExtAttributes', 'TLD' => tld)
|
210
|
+
response = execute(query)
|
211
|
+
return nil unless response['Attributes']
|
212
|
+
[response['Attributes']['Attribute']].flatten.map do |enom_attribute|
|
213
|
+
extended_attribute = Registrar::ExtendedAttributeDescriptor.new
|
214
|
+
extended_attribute.name = enom_attribute['Name']
|
215
|
+
extended_attribute.description = enom_attribute['Description']
|
216
|
+
extended_attribute.child = enom_attribute['IsChild'] == '1'
|
217
|
+
extended_attribute.required = enom_attribute['Required'] == '1'
|
218
|
+
extended_attribute.application = enom_attribute['Application']
|
219
|
+
extended_attribute.user_defined = enom_attribute['UserDefined'] == 'True'
|
220
|
+
extended_attribute.apply_to_registrar = enom_attribute['Application'] == '2'
|
221
|
+
|
222
|
+
if enom_attribute['Options']
|
223
|
+
extended_attribute.options = [enom_attribute['Options']['Option']].flatten.map do |enom_option|
|
224
|
+
option = Registrar::ExtendedAttributeOptionDescriptor.new
|
225
|
+
option.title = enom_option['Title']
|
226
|
+
option.value = enom_option['Value']
|
227
|
+
option.description = enom_option['Description']
|
228
|
+
option
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
extended_attribute
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
def minimum_number_of_years(tld)
|
237
|
+
{
|
238
|
+
'co.uk' => 2,
|
239
|
+
'org.uk' => 2,
|
240
|
+
'nu' => 2,
|
241
|
+
'tm' => 10,
|
242
|
+
'com.mx' => 2,
|
243
|
+
'me.uk' => 2
|
244
|
+
}[tld] || 1
|
245
|
+
end
|
246
|
+
|
247
|
+
def tld_retail_transfer_price(tld)
|
248
|
+
Enom::PricingEngine.tld_retail_transfer_price(tld)
|
249
|
+
end
|
250
|
+
|
251
|
+
# Get a Hash of all of the contacts for the domain. The Hash will have the following
|
252
|
+
# key/value pairs:
|
253
|
+
#
|
254
|
+
# * :registrant => The domain registrant
|
255
|
+
# * :aux_billing => An customer specified billing contact
|
256
|
+
# * :tech => The technical contact for the domain
|
257
|
+
# * :admin => The administrative contact for the domain
|
258
|
+
# * :billing => The Enom billing contact (DNSimple)
|
259
|
+
def contacts(domain)
|
260
|
+
sld, tld = parse(domain.name)
|
261
|
+
|
262
|
+
query = base_query.merge('Command' => 'GetContacts', 'TLD' => tld, 'SLD' => sld)
|
263
|
+
|
264
|
+
response = execute(query)
|
265
|
+
|
266
|
+
contacts = {}
|
267
|
+
registrant_hash = response['GetContacts']['Registrant']
|
268
|
+
contacts[:registrant] = Enom::Contact.from_response('Registrant', registrant_hash)
|
269
|
+
aux_billing_hash = response['GetContacts']['AuxBilling']
|
270
|
+
contacts[:aux_billing] = Enom::Contact.from_response('AuxBilling', aux_billing_hash)
|
271
|
+
|
272
|
+
tech_hash = response['GetContacts']['Tech']
|
273
|
+
contacts[:tech] = Enom::Contact.from_response('Tech', tech_hash)
|
274
|
+
|
275
|
+
admin_hash = response['GetContacts']['Admin']
|
276
|
+
contacts[:admin] = Enom::Contact.from_response('Admin', admin_hash)
|
277
|
+
|
278
|
+
billing_hash = response['GetContacts']['Billing']
|
279
|
+
contacts[:billing] = Enom::Contact.from_response('Billing', billing_hash)
|
280
|
+
|
281
|
+
contacts
|
282
|
+
end
|
283
|
+
|
284
|
+
# Update the registrant information for a domain. For some TLDs this will include
|
285
|
+
# providing extended attributes. If the TLD does not require extended attributes
|
286
|
+
# then send nil or an empty Hash for the extended_attributes argument.
|
287
|
+
def update_registrant(domain, registrant, extended_attributes=nil)
|
288
|
+
registrant = Enom::Contact.new(registrant)
|
289
|
+
|
290
|
+
sld, tld = parse(domain.name)
|
291
|
+
query = base_query.merge(
|
292
|
+
'Command' => 'Contacts',
|
293
|
+
'TLD' => tld,
|
294
|
+
'SLD' => sld
|
295
|
+
)
|
296
|
+
|
297
|
+
query = query.merge('ContactType' => 'Registrant')
|
298
|
+
query = query.merge(registrant.to_query('Registrant'))
|
299
|
+
|
300
|
+
if extended_attributes
|
301
|
+
extended_attributes.each do |name, value|
|
302
|
+
query[name] = value
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
response = execute_command(query) # TODO: should something else be returned here?
|
307
|
+
end
|
308
|
+
|
309
|
+
# Update the tech, aux billing and administrative contacts for the domain. Right
|
310
|
+
# now the same contact must be used for all of these contact types.
|
311
|
+
def update_contacts(domain, contact)
|
312
|
+
contact = Enom::Contact.new(contact)
|
313
|
+
|
314
|
+
sld, tld = parse(domain.name)
|
315
|
+
query = base_query.merge(
|
316
|
+
'Command' => 'Contacts',
|
317
|
+
'TLD' => tld,
|
318
|
+
'SLD' => sld
|
319
|
+
)
|
320
|
+
|
321
|
+
tech_contact_query = query.merge('ContactType' => 'Tech')
|
322
|
+
tech_contact_query = tech_contact_query.merge(contact.to_query('Tech'))
|
323
|
+
response = execute_command(tech_contact_query)
|
324
|
+
|
325
|
+
admin_contact_query = query.merge('ContactType' => 'Admin')
|
326
|
+
admin_contact_query = admin_contact_query.merge(contact.to_query('Admin'))
|
327
|
+
response = execute_command(admin_contact_query)
|
328
|
+
|
329
|
+
billing_contact_query = query.merge('ContactType' => 'AuxBilling')
|
330
|
+
billing_contact_query = billing_contact_query.merge(contact.to_query('AuxBilling'))
|
331
|
+
response = execute(billing_contact_query)
|
332
|
+
|
333
|
+
contacts(domain)
|
334
|
+
end
|
335
|
+
|
336
|
+
# Update the tech contact for the domain.
|
337
|
+
def update_technical_contact(domain, contact)
|
338
|
+
contact = Enom::Contact.new(contact)
|
339
|
+
|
340
|
+
sld, tld = parse(domain.name)
|
341
|
+
query = base_query.merge(
|
342
|
+
'Command' => 'Contacts',
|
343
|
+
'TLD' => tld,
|
344
|
+
'SLD' => sld
|
345
|
+
)
|
346
|
+
|
347
|
+
query = query.merge('ContactType' => 'Tech')
|
348
|
+
query = query.merge(contact.to_query('Tech'))
|
349
|
+
response = execute(query)
|
350
|
+
contacts(domain)[:tech]
|
351
|
+
end
|
352
|
+
|
353
|
+
# Update the admin contact for the domain.
|
354
|
+
def update_administrative_contact(domain, contact)
|
355
|
+
contact = Enom::Contact.new(contact)
|
356
|
+
|
357
|
+
sld, tld = parse(domain.name)
|
358
|
+
query = base_query.merge(
|
359
|
+
'Command' => 'Contacts',
|
360
|
+
'TLD' => tld,
|
361
|
+
'SLD' => sld
|
362
|
+
)
|
363
|
+
|
364
|
+
query = query.merge('ContactType' => 'Admin')
|
365
|
+
query = query.merge(contact.to_query('Admin'))
|
366
|
+
response = execute(query)
|
367
|
+
contacts(domain)[:admin]
|
368
|
+
end
|
369
|
+
|
370
|
+
# Update the aux billing contact for the domain.
|
371
|
+
def update_aux_billing_contact(domain, contact)
|
372
|
+
contact = Enom::Contact.new(contact)
|
373
|
+
|
374
|
+
sld, tld = parse(domain.name)
|
375
|
+
query = base_query.merge(
|
376
|
+
'Command' => 'Contacts',
|
377
|
+
'TLD' => tld,
|
378
|
+
'SLD' => sld
|
379
|
+
)
|
380
|
+
|
381
|
+
query = query.merge('ContactType' => 'AuxBilling')
|
382
|
+
query = query.merge(contact.to_query('AuxBilling'))
|
383
|
+
response = execute(query)
|
384
|
+
contacts(domain)[:aux_billing]
|
385
|
+
end
|
386
|
+
|
387
|
+
private
|
388
|
+
def execute(query)
|
389
|
+
Encoding.default_internal = Encoding.default_external = "UTF-8"
|
390
|
+
options = {:query => query, :parser => EnomParser}
|
391
|
+
response = self.class.get(url, options)['interface_response']
|
392
|
+
raise Registrar::RegistrarError.new("Response from Enom was nil") if response.nil?
|
393
|
+
raise EnomError.new(response) if response['ErrCount'] != '0'
|
394
|
+
response
|
395
|
+
end
|
396
|
+
alias :execute_command :execute
|
397
|
+
|
398
|
+
def base_query
|
399
|
+
{
|
400
|
+
'UID' => username,
|
401
|
+
'PW' => password,
|
402
|
+
'ResponseType' => 'XML'
|
403
|
+
}
|
404
|
+
end
|
405
|
+
|
406
|
+
end
|
407
|
+
|
408
|
+
class EnomError < Registrar::RegistrarError
|
409
|
+
attr_reader :response
|
410
|
+
attr_reader :errors
|
411
|
+
|
412
|
+
def initialize(response)
|
413
|
+
@response = response
|
414
|
+
@errors = []
|
415
|
+
|
416
|
+
response['errors'].each do |k, err|
|
417
|
+
@errors << err
|
418
|
+
end
|
419
|
+
|
420
|
+
super response['errors'].values.join(", ")
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
class EnomParser < HTTParty::Parser
|
425
|
+
def body
|
426
|
+
@body.force_encoding('UTF-8')
|
427
|
+
end
|
428
|
+
end
|
429
|
+
end
|
430
|
+
end
|