epp-client-base 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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