epp-client-base 0.11.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/ChangeLog +5 -0
- data/Gemfile +6 -0
- data/MIT-LICENSE +19 -0
- data/README +5 -0
- data/Rakefile +37 -0
- data/epp-client-base.gemspec +54 -0
- data/lib/epp-client/base.rb +113 -0
- data/lib/epp-client/connection.rb +78 -0
- data/lib/epp-client/contact.rb +398 -0
- data/lib/epp-client/domain.rb +394 -0
- data/lib/epp-client/exceptions.rb +21 -0
- data/lib/epp-client/poll.rb +69 -0
- data/lib/epp-client/session.rb +56 -0
- data/lib/epp-client/ssl.rb +46 -0
- data/lib/epp-client/version.rb +3 -0
- data/lib/epp-client/xml.rb +150 -0
- data/vendor/ietf/contact-1.0.xsd +388 -0
- data/vendor/ietf/domain-1.0.xsd +430 -0
- data/vendor/ietf/epp-1.0.xsd +444 -0
- data/vendor/ietf/eppcom-1.0.xsd +105 -0
- data/vendor/ietf/host-1.0.xsd +240 -0
- data/vendor/ietf/rfc4310.txt +1235 -0
- data/vendor/ietf/rfc5730.txt +3755 -0
- data/vendor/ietf/rfc5731.txt +2467 -0
- data/vendor/ietf/rfc5732.txt +1627 -0
- data/vendor/ietf/rfc5733.txt +2299 -0
- data/vendor/ietf/rfc5734.txt +731 -0
- data/vendor/ietf/rfc5910.txt +2019 -0
- metadata +143 -0
@@ -0,0 +1,398 @@
|
|
1
|
+
module EPPClient
|
2
|
+
module Contact
|
3
|
+
EPPClient::Poll::PARSERS['contact:infData'] = :contact_info_process
|
4
|
+
|
5
|
+
def contact_check_xml(*contacts) #:nodoc:
|
6
|
+
command do |xml|
|
7
|
+
xml.check do
|
8
|
+
xml.check('xmlns' => EPPClient::SCHEMAS_URL['contact-1.0']) do
|
9
|
+
contacts.each do |c|
|
10
|
+
xml.id(c)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Check the availability of contacts
|
18
|
+
#
|
19
|
+
# takes list of contacts as arguments
|
20
|
+
#
|
21
|
+
# returns an array of hashes containing three fields :
|
22
|
+
# [<tt>:id</tt>] the contact id
|
23
|
+
# [<tt>:avail</tt>] wether the contact id can be provisionned.
|
24
|
+
# [<tt>:reason</tt>]
|
25
|
+
# the server-specific text to help explain why the object cannot be
|
26
|
+
# provisioned.
|
27
|
+
#
|
28
|
+
def contact_check(*contacts)
|
29
|
+
contacts.flatten!
|
30
|
+
|
31
|
+
response = send_request(contact_check_xml(*contacts))
|
32
|
+
get_result(:xml => response, :callback => :contact_check_process)
|
33
|
+
end
|
34
|
+
|
35
|
+
def contact_check_process(xml) #:nodoc:
|
36
|
+
xml.xpath('epp:resData/contact:chkData/contact:cd', EPPClient::SCHEMAS_URL).map do |dom|
|
37
|
+
ret = {
|
38
|
+
:name => dom.xpath('contact:id', EPPClient::SCHEMAS_URL).text,
|
39
|
+
:avail => dom.xpath('contact:id', EPPClient::SCHEMAS_URL).attr('avail').value == '1',
|
40
|
+
}
|
41
|
+
unless (reason = dom.xpath('contact:reason', EPPClient::SCHEMAS_URL).text).empty?
|
42
|
+
ret[:reason] = reason
|
43
|
+
end
|
44
|
+
ret
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def contact_info_xml(args) #:nodoc:
|
49
|
+
command do |xml|
|
50
|
+
xml.info do
|
51
|
+
xml.info('xmlns' => EPPClient::SCHEMAS_URL['contact-1.0']) do
|
52
|
+
xml.id(args[:id])
|
53
|
+
if args.key?(:authInfo)
|
54
|
+
xml.authInfo do
|
55
|
+
xml.pw(args[:authInfo])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns the informations about a contact
|
64
|
+
#
|
65
|
+
# Takes either a unique argument, either
|
66
|
+
# a string, representing the contact id
|
67
|
+
# or a hash with the following keys :
|
68
|
+
# [<tt>:id</tt>] the contact id, and optionnaly
|
69
|
+
# [<tt>:authInfo</tt>] an optional authentication information.
|
70
|
+
#
|
71
|
+
# Returned is a hash mapping as closely as possible the result expected
|
72
|
+
# from the command as per Section 3.1.2 of RFC 5733 :
|
73
|
+
# [<tt>:id</tt>]
|
74
|
+
# the server-unique identifier of the contact object. Most of the time,
|
75
|
+
# the nic handle.
|
76
|
+
# [<tt>:roid</tt>]
|
77
|
+
# the Repository Object IDentifier assigned to the contact object when
|
78
|
+
# the object was created.
|
79
|
+
# [<tt>:status</tt>] the status of the contact object.
|
80
|
+
# [<tt>:postalInfo</tt>]
|
81
|
+
# a hash containing one or two keys, +loc+ and +int+ representing the
|
82
|
+
# localized and internationalized version of the postal address
|
83
|
+
# information. The value is a hash with the following keys :
|
84
|
+
# [<tt>:name</tt>]
|
85
|
+
# the name of the individual or role represented by the contact.
|
86
|
+
# [<tt>:org</tt>]
|
87
|
+
# the name of the organization with which the contact is affiliated.
|
88
|
+
# [<tt>:addr</tt>]
|
89
|
+
# a hash with the following keys :
|
90
|
+
# [<tt>:street</tt>]
|
91
|
+
# an array that contains the contact's street address.
|
92
|
+
# [<tt>:city</tt>] the contact's city.
|
93
|
+
# [<tt>:sp</tt>] the contact's state or province.
|
94
|
+
# [<tt>:pc</tt>] the contact's postal code.
|
95
|
+
# [<tt>:cc</tt>] the contact's country code.
|
96
|
+
# [<tt>:voice</tt>] the contact's optional voice telephone number.
|
97
|
+
# [<tt>:fax</tt>] the contact's optional facsimile telephone number.
|
98
|
+
# [<tt>:email</tt>] the contact's email address.
|
99
|
+
# [<tt>:clID</tt>] the identifier of the sponsoring client.
|
100
|
+
# [<tt>:crID</tt>]
|
101
|
+
# the identifier of the client that created the contact object.
|
102
|
+
# [<tt>:crDate</tt>] the date and time of contact-object creation.
|
103
|
+
# [<tt>:upID</tt>]
|
104
|
+
# the optional identifier of the client that last updated the contact
|
105
|
+
# object.
|
106
|
+
# [<tt>:upDate</tt>]
|
107
|
+
# the optional date and time of the most recent contact-object
|
108
|
+
# modification.
|
109
|
+
# [<tt>:trDate</tt>]
|
110
|
+
# the optional date and time of the most recent successful contact-object
|
111
|
+
# transfer.
|
112
|
+
# [<tt>:authInfo</tt>]
|
113
|
+
# authorization information associated with the contact object.
|
114
|
+
# [<tt>:disclose</tt>]
|
115
|
+
# an optional array that identifies elements that require exceptional
|
116
|
+
# server-operator handling to allow or restrict disclosure to third
|
117
|
+
# parties. See
|
118
|
+
# section 2.9[http://tools.ietf.org/html/rfc5733#section-2.9] of RFC 5733
|
119
|
+
# for details.
|
120
|
+
def contact_info(args)
|
121
|
+
if String === args
|
122
|
+
args = {:id => args}
|
123
|
+
end
|
124
|
+
response = send_request(contact_info_xml(args))
|
125
|
+
|
126
|
+
get_result(:xml => response, :callback => :contact_info_process)
|
127
|
+
end
|
128
|
+
|
129
|
+
def contact_info_process(xml) #:nodoc:
|
130
|
+
contact = xml.xpath('epp:resData/contact:infData', EPPClient::SCHEMAS_URL)
|
131
|
+
ret = {
|
132
|
+
:id => contact.xpath('contact:id', EPPClient::SCHEMAS_URL).text,
|
133
|
+
:roid => contact.xpath('contact:roid', EPPClient::SCHEMAS_URL).text,
|
134
|
+
}
|
135
|
+
if (status = contact.xpath('contact:status', EPPClient::SCHEMAS_URL)).size > 0
|
136
|
+
ret[:status] = status.map {|s| s.attr('s')}
|
137
|
+
end
|
138
|
+
|
139
|
+
if (postalInfo = contact.xpath('contact:postalInfo', EPPClient::SCHEMAS_URL)).size > 0
|
140
|
+
ret[:postalInfo] = postalInfo.inject({}) do |acc, p|
|
141
|
+
type = p.attr('type').to_sym
|
142
|
+
acc[type] = { :name => p.xpath('contact:name', EPPClient::SCHEMAS_URL).text, :addr => {} }
|
143
|
+
if (org = p.xpath('contact:org', EPPClient::SCHEMAS_URL)).size > 0
|
144
|
+
acc[type][:org] = org.text
|
145
|
+
end
|
146
|
+
addr = p.xpath('contact:addr', EPPClient::SCHEMAS_URL)
|
147
|
+
|
148
|
+
acc[type][:addr][:street] = addr.xpath('contact:street', EPPClient::SCHEMAS_URL).map {|s| s.text}
|
149
|
+
%w(city cc).each do |val|
|
150
|
+
acc[type][:addr][val.to_sym] = addr.xpath("contact:#{val}", EPPClient::SCHEMAS_URL).text
|
151
|
+
end
|
152
|
+
%w(sp pc).each do |val|
|
153
|
+
if (r = addr.xpath("contact:#{val}", EPPClient::SCHEMAS_URL)).size > 0
|
154
|
+
acc[type][:addr][val.to_sym] = r.text
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
acc
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
%w(voice fax email clID crID upID).each do |val|
|
163
|
+
if (value = contact.xpath("contact:#{val}", EPPClient::SCHEMAS_URL)).size > 0
|
164
|
+
ret[val.to_sym] = value.text
|
165
|
+
end
|
166
|
+
end
|
167
|
+
%w(crDate upDate trDate).each do |val|
|
168
|
+
if (date = contact.xpath("contact:#{val}", EPPClient::SCHEMAS_URL)).size > 0
|
169
|
+
ret[val.to_sym] = DateTime.parse(date.text)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
if (authInfo = contact.xpath('contact:authInfo', EPPClient::SCHEMAS_URL)).size > 0
|
173
|
+
ret[:authInfo] = authInfo.xpath('contact:pw', EPPClient::SCHEMAS_URL).text
|
174
|
+
end
|
175
|
+
if (disclose = contact.xpath('contact:disclose', EPPClient::SCHEMAS_URL)).size > 0
|
176
|
+
ret[:disclose] = { :flag => disclose.attr('flag').value == '1', :elements => [] }
|
177
|
+
disclose.children.each do |c|
|
178
|
+
r = { :name => c.name }
|
179
|
+
unless (type = c.attr('type').value).nil?
|
180
|
+
r[:type] == type
|
181
|
+
end
|
182
|
+
ret[:disclose][:elements] << r
|
183
|
+
end
|
184
|
+
end
|
185
|
+
ret
|
186
|
+
end
|
187
|
+
|
188
|
+
def contact_create_xml(contact) #:nodoc:
|
189
|
+
command do |xml|
|
190
|
+
xml.create do
|
191
|
+
xml.create('xmlns' => EPPClient::SCHEMAS_URL['contact-1.0']) do
|
192
|
+
if contact.key?(:id)
|
193
|
+
xml.id(contact[:id])
|
194
|
+
else
|
195
|
+
xml.id('invalid')
|
196
|
+
end
|
197
|
+
contact[:postalInfo].each do |type,infos|
|
198
|
+
xml.postalInfo :type => type do
|
199
|
+
xml.name(infos[:name])
|
200
|
+
xml.org(infos[:org]) if infos.key?(:org)
|
201
|
+
xml.addr do
|
202
|
+
infos[:addr][:street].each do |street|
|
203
|
+
xml.street(street)
|
204
|
+
end
|
205
|
+
xml.city(infos[:addr][:city])
|
206
|
+
[:sp, :pc].each do |val|
|
207
|
+
xml.__send__(val, infos[:addr][val]) if infos[:addr].key?(val)
|
208
|
+
end
|
209
|
+
xml.cc(infos[:addr][:cc])
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
[:voice, :fax].each do |val|
|
214
|
+
xml.__send__(val, contact[val]) if contact.key?(val)
|
215
|
+
end
|
216
|
+
xml.email(contact[:email])
|
217
|
+
xml.authInfo do
|
218
|
+
xml.pw(contact[:authInfo])
|
219
|
+
end
|
220
|
+
if contact.key?(:disclose)
|
221
|
+
xml.disclose do
|
222
|
+
contact[:disclose].each do |disc|
|
223
|
+
if disc.key?(:type)
|
224
|
+
xml.__send__(disc[:name], :type => disc[:type])
|
225
|
+
else
|
226
|
+
xml.__send__(disc[:name])
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
# Creates a contact
|
237
|
+
#
|
238
|
+
# Takes a hash as an argument containing the following keys :
|
239
|
+
#
|
240
|
+
# [<tt>:id</tt>]
|
241
|
+
# the server-unique identifier of the contact object. Most of the time,
|
242
|
+
# the nic handle.
|
243
|
+
# [<tt>:postalInfo</tt>]
|
244
|
+
# a hash containing one or two keys, +loc+ and +int+ representing the
|
245
|
+
# localized and internationalized version of the postal address
|
246
|
+
# information. The value is a hash with the following keys :
|
247
|
+
# [<tt>:name</tt>]
|
248
|
+
# the name of the individual or role represented by the contact.
|
249
|
+
# [<tt>:org</tt>]
|
250
|
+
# the name of the organization with which the contact is affiliated.
|
251
|
+
# [<tt>:addr</tt>]
|
252
|
+
# a hash with the following keys :
|
253
|
+
# [<tt>:street</tt>]
|
254
|
+
# an array that contains the contact's street address.
|
255
|
+
# [<tt>:city</tt>] the contact's city.
|
256
|
+
# [<tt>:sp</tt>] the contact's state or province.
|
257
|
+
# [<tt>:pc</tt>] the contact's postal code.
|
258
|
+
# [<tt>:cc</tt>] the contact's country code.
|
259
|
+
# [<tt>:voice</tt>] the contact's optional voice telephone number.
|
260
|
+
# [<tt>:fax</tt>] the contact's optional facsimile telephone number.
|
261
|
+
# [<tt>:email</tt>] the contact's email address.
|
262
|
+
# [<tt>:authInfo</tt>]
|
263
|
+
# authorization information associated with the contact object.
|
264
|
+
# [<tt>:disclose</tt>]
|
265
|
+
# an optional array that identifies elements that require exceptional
|
266
|
+
# server-operator handling to allow or restrict disclosure to third
|
267
|
+
# parties. See
|
268
|
+
# section 2.9[http://tools.ietf.org/html/rfc5733#section-2.9] of RFC 5733
|
269
|
+
# for details.
|
270
|
+
#
|
271
|
+
# Returns a hash with the following keys :
|
272
|
+
#
|
273
|
+
# [<tt>:id</tt>] the nic handle.
|
274
|
+
# [<tt>:crDate</tt>] the date and time of contact-object creation.
|
275
|
+
def contact_create(contact)
|
276
|
+
response = send_request(contact_create_xml(contact))
|
277
|
+
|
278
|
+
get_result(:xml => response, :callback => :contact_create_process)
|
279
|
+
end
|
280
|
+
|
281
|
+
def contact_create_process(xml) #:nodoc:
|
282
|
+
contact = xml.xpath('epp:resData/contact:creData', EPPClient::SCHEMAS_URL)
|
283
|
+
{
|
284
|
+
:id => contact.xpath('contact:id', EPPClient::SCHEMAS_URL).text,
|
285
|
+
:crDate => DateTime.parse(contact.xpath('contact:crDate', EPPClient::SCHEMAS_URL).text),
|
286
|
+
}
|
287
|
+
end
|
288
|
+
|
289
|
+
def contact_delete_xml(contact) #:nodoc:
|
290
|
+
command do |xml|
|
291
|
+
xml.delete do
|
292
|
+
xml.delete('xmlns' => EPPClient::SCHEMAS_URL['contact-1.0']) do
|
293
|
+
xml.id(contact)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
# Deletes a contact
|
300
|
+
#
|
301
|
+
# Takes a single nic handle for argument.
|
302
|
+
#
|
303
|
+
# Returns true on success, or raises an exception.
|
304
|
+
def contact_delete(contact)
|
305
|
+
response = send_request(contact_delete_xml(contact))
|
306
|
+
|
307
|
+
get_result(response)
|
308
|
+
end
|
309
|
+
|
310
|
+
def contact_update_xml(args) #:nodoc:
|
311
|
+
command do |xml|
|
312
|
+
xml.update do
|
313
|
+
xml.update('xmlns' => EPPClient::SCHEMAS_URL['contact-1.0']) do
|
314
|
+
xml.id args[:id]
|
315
|
+
if args.key?(:add) && args[:add].key?(:status)
|
316
|
+
xml.add do
|
317
|
+
args[:add][:status].each do |s|
|
318
|
+
xml.status :s => s
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|
322
|
+
if args.key?(:rem) && args[:rem].key?(:status)
|
323
|
+
xml.rem do
|
324
|
+
args[:rem][:status].each do |s|
|
325
|
+
xml.status :s => s
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
if args.key?(:chg)
|
330
|
+
contact = args[:chg]
|
331
|
+
xml.chg do
|
332
|
+
if contact.key?(:postalInfo)
|
333
|
+
contact[:postalInfo].each do |type,infos|
|
334
|
+
xml.postalInfo :type => type do
|
335
|
+
xml.name(infos[:name])
|
336
|
+
xml.org(infos[:org]) if infos.key?(:org)
|
337
|
+
xml.addr do
|
338
|
+
infos[:addr][:street].each do |street|
|
339
|
+
xml.street(street)
|
340
|
+
end
|
341
|
+
xml.city(infos[:addr][:city])
|
342
|
+
[:sp, :pc].each do |val|
|
343
|
+
xml.__send__(val, infos[:addr][val]) if infos[:addr].key?(val)
|
344
|
+
end
|
345
|
+
xml.cc(infos[:addr][:cc])
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
[:voice, :fax, :email].each do |val|
|
351
|
+
xml.__send__(val, contact[val]) if contact.key?(val)
|
352
|
+
end
|
353
|
+
if contact.key?(:authInfo)
|
354
|
+
xml.authInfo do
|
355
|
+
xml.pw(contact[:authInfo])
|
356
|
+
end
|
357
|
+
end
|
358
|
+
if contact.key?(:disclose)
|
359
|
+
xml.disclose do
|
360
|
+
contact[:disclose].each do |disc|
|
361
|
+
if disc.key?(:type)
|
362
|
+
xml.__send__(disc[:name], :type => disc[:type])
|
363
|
+
else
|
364
|
+
xml.__send__(disc[:name])
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
# Updates a contact
|
377
|
+
#
|
378
|
+
# Takes a hash with the id, and at least one of the following keys :
|
379
|
+
# [<tt>:id</tt>]
|
380
|
+
# the server-unique identifier of the contact object to be updated.
|
381
|
+
# [<tt>:add</tt>/<tt>:rem</tt>]
|
382
|
+
# adds or removes the following data from the contact object :
|
383
|
+
# [<tt>:status</tt>] an array of status to add to/remove from the object.
|
384
|
+
# [<tt>:chg</tt>]
|
385
|
+
# changes the datas of the contact object, takes the same arguments as
|
386
|
+
# the creation of the contact, except the id, with the small change that
|
387
|
+
# each first level key is now optional. (Meaning that you don't have to
|
388
|
+
# supply a <tt>:postalInfo</tt> if you don't need to, but if you do, all
|
389
|
+
# it's mandatory fields are mandatory.)
|
390
|
+
#
|
391
|
+
# Returns true on success, or raises an exception.
|
392
|
+
def contact_update(args)
|
393
|
+
response = send_request(contact_update_xml(args))
|
394
|
+
|
395
|
+
get_result(response)
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|