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.
@@ -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