kono_epp_client 0.1.0 → 2.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +46 -0
- data/Makefile +13 -0
- data/README.md +33 -0
- data/Rakefile +6 -0
- data/kono_epp_client.gemspec +42 -0
- data/lib/kono_epp_client/VERSION +1 -0
- data/lib/kono_epp_client/commands/check_contacts.rb +19 -0
- data/lib/{epp/epp_command/kono_epp_check_domains.rb → kono_epp_client/commands/check_domains.rb} +3 -1
- data/lib/kono_epp_client/commands/command.rb +15 -0
- data/lib/kono_epp_client/commands/create_contact.rb +89 -0
- data/lib/kono_epp_client/commands/create_domain.rb +56 -0
- data/lib/kono_epp_client/commands/delete_contact.rb +17 -0
- data/lib/kono_epp_client/commands/delete_domain.rb +16 -0
- data/lib/kono_epp_client/commands/hello.rb +15 -0
- data/lib/kono_epp_client/commands/info_contact.rb +17 -0
- data/lib/kono_epp_client/commands/info_domain.rb +16 -0
- data/lib/kono_epp_client/commands/login.rb +84 -0
- data/lib/kono_epp_client/commands/logout.rb +12 -0
- data/lib/kono_epp_client/commands/poll.rb +18 -0
- data/lib/kono_epp_client/commands/transfer_domain.rb +38 -0
- data/lib/kono_epp_client/commands/update_contact.rb +116 -0
- data/lib/kono_epp_client/commands/update_domain.rb +117 -0
- data/lib/kono_epp_client/dns_sec/add.rb +13 -0
- data/lib/kono_epp_client/dns_sec/ds_data.rb +65 -0
- data/lib/kono_epp_client/dns_sec/rem.rb +14 -0
- data/lib/kono_epp_client/dns_sec/rem_all.rb +10 -0
- data/lib/kono_epp_client/exceptions/error_response.rb +19 -0
- data/lib/kono_epp_client/exceptions.rb +15 -0
- data/lib/kono_epp_client/requires_parameters.rb +16 -0
- data/lib/kono_epp_client/server.rb +311 -0
- data/lib/kono_epp_client/version.rb +3 -0
- data/lib/kono_epp_client.rb +4 -16
- data/spec/eager_load_spec.rb +6 -0
- data/spec/factories/ds_data.rb +12 -0
- data/spec/fixtures/dns_sec/add.xml +14 -0
- data/spec/fixtures/dns_sec/ds_data.xml +6 -0
- data/spec/fixtures/dns_sec/rem.xml +14 -0
- data/spec/fixtures/dns_sec/rem_all.xml +3 -0
- data/spec/fixtures/login_response.xml +23 -0
- data/spec/fixtures/login_response_for_dnssec.xml +25 -0
- data/spec/fixtures/snapshots/kono_epp_client/commands/create_domain/_create_with_ds_data_build_extensions.xml.snap +39 -0
- data/spec/fixtures/snapshots/kono_epp_client/commands/login/_login.xml.snap +7 -0
- data/spec/fixtures/snapshots/kono_epp_client/commands/login/_tags_extensions_with_value_xml.xml.snap +14 -0
- data/spec/fixtures/snapshots/kono_epp_client/commands/login/_tags_lang_with_value_xml.xml.snap +11 -0
- data/spec/fixtures/snapshots/kono_epp_client/commands/login/_tags_new_password_with_value_xml.xml.snap +9 -0
- data/spec/fixtures/snapshots/kono_epp_client/commands/login/_tags_services_with_value_xml.xml.snap +12 -0
- data/spec/fixtures/snapshots/kono_epp_client/commands/login/_tags_version_with_value_xml.xml.snap +11 -0
- data/spec/fixtures/snapshots/kono_epp_client/commands/login/_with_id_and_password_login.xml.snap +10 -0
- data/spec/fixtures/snapshots/kono_epp_client/commands/update_domain/_update_DnsSec_build_extensions.xml.snap +30 -0
- data/spec/{epp/epp_command/kono_epp_check_contacts_spec.rb → lib/commands/check_contacts_spec.rb} +1 -1
- data/spec/{epp/epp_command/kono_epp_check_domains_spec.rb → lib/commands/check_domains_spec.rb} +1 -1
- data/spec/{epp/kono_epp_command_spec.rb → lib/commands/command_spec.rb} +2 -2
- data/spec/lib/commands/create_domain_spec.rb +50 -0
- data/spec/lib/commands/login_spec.rb +87 -0
- data/spec/{epp/epp_command/kono_epp_transfer_domain_spec.rb → lib/commands/transfer_domain_spec.rb} +1 -1
- data/spec/{epp/epp_command/kono_epp_update_domain_spec.rb → lib/commands/update_domain_spec.rb} +20 -4
- data/spec/lib/dns_sec/add_spec.rb +14 -0
- data/spec/lib/dns_sec/ds_data_spec.rb +43 -0
- data/spec/lib/dns_sec/rem_all_spec.rb +11 -0
- data/spec/lib/dns_sec/rem_spec.rb +14 -0
- data/spec/lib/server_spec.rb +304 -0
- data/spec/spec_helper.rb +6 -2
- data/spec/support/context.rb +1 -1
- data/spec/support/factory_bot.rb +8 -0
- data/spec/support/fixtures.rb +16 -0
- data/spec/support/matchers.rb +14 -0
- data/spec/support/parametric.rb +1 -0
- data/spec/support/snapshot.rb +13 -3
- data/spec/support/superdiff.rb +1 -0
- metadata +178 -58
- data/lib/epp/epp_command/check_contacts.rb +0 -17
- data/lib/epp/epp_command/create_contact.rb +0 -87
- data/lib/epp/epp_command/create_domain.rb +0 -44
- data/lib/epp/epp_command/delete_contact.rb +0 -15
- data/lib/epp/epp_command/delete_domain.rb +0 -14
- data/lib/epp/epp_command/hello.rb +0 -13
- data/lib/epp/epp_command/info_contact.rb +0 -15
- data/lib/epp/epp_command/info_domain.rb +0 -14
- data/lib/epp/epp_command/login.rb +0 -79
- data/lib/epp/epp_command/logout.rb +0 -10
- data/lib/epp/epp_command/poll.rb +0 -16
- data/lib/epp/epp_command/transfer_domain.rb +0 -36
- data/lib/epp/epp_command/update_contact.rb +0 -115
- data/lib/epp/epp_command/update_domain.rb +0 -104
- data/lib/epp/epp_command.rb +0 -15
- data/lib/epp/exceptions.rb +0 -28
- data/lib/epp/server.rb +0 -295
- data/lib/epp/transport/tcp.rb +0 -93
- data/lib/require_parameters.rb +0 -14
- data/spec/epp/epp_command/kono_epp_create_domain_spec.rb +0 -37
- /data/lib/{epp/transport/http.rb → kono_epp_client/transport/http_transport.rb} +0 -0
- /data/lib/{epp → kono_epp_client}/transport.rb +0 -0
- /data/spec/fixtures/snapshots/{kono_epp_check_contacts → kono_epp_client/commands/check_contacts}/_construct.xml.snap +0 -0
- /data/spec/fixtures/snapshots/{kono_epp_check_domains → kono_epp_client/commands/check_domains}/_construct.xml.snap +0 -0
- /data/spec/fixtures/snapshots/{kono_epp_create_domain → kono_epp_client/commands/create_domain}/_create.xml.snap +0 -0
- /data/spec/fixtures/snapshots/{kono_epp_transfer_domain → kono_epp_client/commands/transfer_domain}/_con_extension_construct.xml.snap +0 -0
- /data/spec/fixtures/snapshots/{kono_epp_transfer_domain → kono_epp_client/commands/transfer_domain}/_construct.xml.snap +0 -0
- /data/spec/fixtures/snapshots/{kono_epp_update_domain → kono_epp_client/commands/update_domain}/_restore_esiste_l'estensione_di_restore.xml.snap +0 -0
- /data/spec/fixtures/snapshots/{kono_epp_update_domain → kono_epp_client/commands/update_domain}/_update_auth_info_cambia_AUTH_INFO.xml.snap +0 -0
- /data/spec/fixtures/snapshots/{kono_epp_update_domain → kono_epp_client/commands/update_domain}/_update_auth_info_con_nuovo_registrant_cambia_REGISTRANT.xml.snap +0 -0
- /data/spec/fixtures/snapshots/{kono_epp_update_domain → kono_epp_client/commands/update_domain}/_update_contacts_cambia_ADMIN_TECH.xml.snap +0 -0
- /data/spec/fixtures/snapshots/{kono_epp_update_domain → kono_epp_client/commands/update_domain}/_update_nameservers_aggiunge_e_rimuove_ns.xml.snap +0 -0
- /data/spec/fixtures/snapshots/{kono_epp_update_domain → kono_epp_client/commands/update_domain}/_update_status_cambia_status.xml.snap +0 -0
@@ -1,36 +0,0 @@
|
|
1
|
-
class KonoEppTransferDomain < KonoEppCommand
|
2
|
-
def initialize(name, authinfo, op, extension: nil)
|
3
|
-
super(nil, nil)
|
4
|
-
|
5
|
-
command = root.elements['command']
|
6
|
-
transfer = command.add_element("transfer", {"op" => op})
|
7
|
-
# FIXME dovremmo controllare che le possibili opzioni di OP sono 'request', 'cancel', 'approve', 'reject', 'query'
|
8
|
-
|
9
|
-
domain_transfer = transfer.add_element("domain:transfer", {"xmlns:domain" => "urn:ietf:params:xml:ns:domain-1.0",
|
10
|
-
"xsi:schemaLocation" => "urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd"})
|
11
|
-
|
12
|
-
domain_name = domain_transfer.add_element "domain:name"
|
13
|
-
domain_name.text = name
|
14
|
-
|
15
|
-
domain_authinfo = domain_transfer.add_element "domain:authInfo"
|
16
|
-
domain_pw = domain_authinfo.add_element "domain:pw"
|
17
|
-
|
18
|
-
domain_pw.text = authinfo
|
19
|
-
|
20
|
-
## Questa estensione è per Modifica del Registrar con contestuale modifica del Registrante
|
21
|
-
if extension
|
22
|
-
|
23
|
-
ext_elm = command.add_element "extension"
|
24
|
-
ext_trade = ext_elm.add_element "extdom:trade", {"xmlns:extdom"=>"http://www.nic.it/ITNIC-EPP/extdom-2.0",
|
25
|
-
"xsi:schemaLocation" => "http://www.nic.it/ITNIC-EPP/extdom-2.0 extdom-2.0.xsd"}
|
26
|
-
|
27
|
-
transfer_trade = ext_trade.add_element "extdom:transferTrade"
|
28
|
-
transfer_trade.add_element("extdom:newRegistrant").text = extension[:new_registrant] if extension[:new_registrant]
|
29
|
-
if extension[:new_auth_info]
|
30
|
-
transfer_trade.add_element("extdom:newAuthInfo").add_element("extdom:pw").tap{|x|x.text=extension[:new_auth_info]}
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|
@@ -1,115 +0,0 @@
|
|
1
|
-
class KonoEppUpdateContact < KonoEppCommand
|
2
|
-
|
3
|
-
# TODO: Add and remove fields
|
4
|
-
def initialize( options )
|
5
|
-
super( nil, nil )
|
6
|
-
|
7
|
-
command = root.elements['command']
|
8
|
-
|
9
|
-
update = command.add_element "update"
|
10
|
-
|
11
|
-
contact_update = update.add_element( "contact:update", { "xmlns:contact" => "urn:ietf:params:xml:ns:contact-1.0",
|
12
|
-
"xsi:schemaLocation" => "urn:ietf:params:xml:ns:contact-1.0 contact-1.0.xsd" } )
|
13
|
-
|
14
|
-
id = contact_update.add_element "contact:id"
|
15
|
-
id.text = options[:id]
|
16
|
-
|
17
|
-
contact_chg = contact_update.add_element "contact:chg"
|
18
|
-
|
19
|
-
unless options[:name].blank? \
|
20
|
-
and options[:organization].blank? \
|
21
|
-
and options[:address].blank? \
|
22
|
-
and options[:city].blank? \
|
23
|
-
and options[:state].blank? \
|
24
|
-
and options[:postal_code].blank? \
|
25
|
-
and options[:country].blank?
|
26
|
-
|
27
|
-
postal_info = contact_chg.add_element "contact:postalInfo", { "type" => "loc" }
|
28
|
-
|
29
|
-
unless options[:name].blank?
|
30
|
-
name = postal_info.add_element "contact:name"
|
31
|
-
name.text = options[:name]
|
32
|
-
end
|
33
|
-
|
34
|
-
unless options[:organization].blank?
|
35
|
-
organization = postal_info.add_element "contact:org"
|
36
|
-
organization.text = options[:organization]
|
37
|
-
end
|
38
|
-
|
39
|
-
# NOTE: city and country are REQUIRED
|
40
|
-
unless options[:address].blank? \
|
41
|
-
and options[:city].blank? \
|
42
|
-
and options[:state].blank? \
|
43
|
-
and options[:postal_code].blank? \
|
44
|
-
and options[:country].blank?
|
45
|
-
|
46
|
-
addr = postal_info.add_element "contact:addr"
|
47
|
-
|
48
|
-
unless options[:address].blank?
|
49
|
-
street = addr.add_element "contact:street"
|
50
|
-
street.text = options[:address]
|
51
|
-
end
|
52
|
-
|
53
|
-
city = addr.add_element "contact:city"
|
54
|
-
city.text = options[:city]
|
55
|
-
|
56
|
-
unless options[:state].blank?
|
57
|
-
state = addr.add_element "contact:sp"
|
58
|
-
state.text = options[:state]
|
59
|
-
end
|
60
|
-
|
61
|
-
unless options[:postal_code].blank?
|
62
|
-
postal_code = addr.add_element "contact:pc"
|
63
|
-
postal_code.text = options[:postal_code]
|
64
|
-
end
|
65
|
-
|
66
|
-
country_code = addr.add_element "contact:cc"
|
67
|
-
country_code.text = options[:country]
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
if options[:voice]
|
72
|
-
voice = contact_chg.add_element "contact:voice"
|
73
|
-
voice.text = options[:voice]
|
74
|
-
end
|
75
|
-
|
76
|
-
if options[:fax]
|
77
|
-
fax = contact_chg.add_element "contact:fax"
|
78
|
-
fax.text = options[:fax]
|
79
|
-
end
|
80
|
-
|
81
|
-
if options[:email]
|
82
|
-
email = contact_chg.add_element "contact:email"
|
83
|
-
email.text = options[:email]
|
84
|
-
end
|
85
|
-
|
86
|
-
|
87
|
-
unless not options.has_key?( :publish ) \
|
88
|
-
and options[:nationality].blank? \
|
89
|
-
and options[:entity_type].blank? \
|
90
|
-
and options[:reg_code].blank?
|
91
|
-
|
92
|
-
# FIXME
|
93
|
-
extension = command.add_element "extension"
|
94
|
-
extension_update = extension.add_element "extcon:update", { "xmlns:extcon" => 'http://www.nic.it/ITNIC-EPP/extcon-1.0',
|
95
|
-
"xsi:schemaLocation" => 'http://www.nic.it/ITNIC-EPP/extcon-1.0 extcon-1.0.xsd' }
|
96
|
-
if options.has_key?( :publish )
|
97
|
-
publish = extension_update.add_element "extcon:consentForPublishing"
|
98
|
-
publish.text = options[:publish]
|
99
|
-
end
|
100
|
-
|
101
|
-
if options[:becomes_registrant]
|
102
|
-
extcon_registrant = extension_update.add_element "extcon:registrant"
|
103
|
-
|
104
|
-
extcon_nationality = extcon_registrant.add_element "extcon:nationalityCode"
|
105
|
-
extcon_nationality.text = options[:nationality]
|
106
|
-
|
107
|
-
extcon_entity = extcon_registrant.add_element "extcon:entityType"
|
108
|
-
extcon_entity.text = options[:entity_type]
|
109
|
-
|
110
|
-
extcon_regcode = extcon_registrant.add_element "extcon:regCode"
|
111
|
-
extcon_regcode.text = options[:reg_code]
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
@@ -1,104 +0,0 @@
|
|
1
|
-
class KonoEppUpdateDomain < KonoEppCommand
|
2
|
-
def initialize(options)
|
3
|
-
super(nil, nil)
|
4
|
-
|
5
|
-
command = root.elements['command']
|
6
|
-
update = command.add_element("update")
|
7
|
-
|
8
|
-
domain_update = update.add_element("domain:update", {"xmlns:domain" => "urn:ietf:params:xml:ns:domain-1.0",
|
9
|
-
"xsi:schemaLocation" => "urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd"})
|
10
|
-
|
11
|
-
name = domain_update.add_element "domain:name"
|
12
|
-
name.text = options[:name]
|
13
|
-
|
14
|
-
if not options[:add_nameservers].blank? or options[:add_admin] or options[:add_tech] or options[:add_status]
|
15
|
-
# <domain:add>
|
16
|
-
domain_add = domain_update.add_element "domain:add"
|
17
|
-
|
18
|
-
unless options[:add_nameservers].blank?
|
19
|
-
domain_add_ns = domain_add.add_element "domain:ns"
|
20
|
-
|
21
|
-
options[:add_nameservers].each do |ns|
|
22
|
-
host_attr = domain_add_ns.add_element "domain:hostAttr"
|
23
|
-
host_name = host_attr.add_element "domain:hostName"
|
24
|
-
|
25
|
-
host_name.text = ns[0]
|
26
|
-
|
27
|
-
# FIXME IPv6
|
28
|
-
if ns[1]
|
29
|
-
host_addr = host_attr.add_element "domain:hostAddr", {"ip" => "v4"}
|
30
|
-
host_addr.text = ns[1]
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
if options[:add_admin]
|
36
|
-
domain_contact = domain_add.add_element "domain:contact", {"type" => "admin"}
|
37
|
-
domain_contact.text = options[:add_admin]
|
38
|
-
end
|
39
|
-
|
40
|
-
if options[:add_status]
|
41
|
-
domain_add.add_element "domain:status", {"s" => options[:add_status]}
|
42
|
-
end
|
43
|
-
|
44
|
-
if options[:add_tech]
|
45
|
-
domain_contact = domain_add.add_element "domain:contact", {"type" => "tech"}
|
46
|
-
domain_contact.text = options[:add_tech]
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
if not options[:remove_nameservers].blank? or options[:remove_admin] or options[:remove_tech] or options[:remove_status]
|
51
|
-
# <domain:rem>
|
52
|
-
domain_remove = domain_update.add_element "domain:rem"
|
53
|
-
|
54
|
-
unless options[:remove_nameservers].blank?
|
55
|
-
domain_remove_ns = domain_remove.add_element "domain:ns"
|
56
|
-
|
57
|
-
options[:remove_nameservers].each do |ns_name|
|
58
|
-
host_attr = domain_remove_ns.add_element "domain:hostAttr"
|
59
|
-
host_name = host_attr.add_element "domain:hostName"
|
60
|
-
|
61
|
-
host_name.text = ns_name
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
if options[:remove_admin]
|
66
|
-
domain_contact = domain_remove.add_element "domain:contact", {"type" => "admin"}
|
67
|
-
domain_contact.text = options[:remove_admin]
|
68
|
-
end
|
69
|
-
|
70
|
-
if options[:remove_status]
|
71
|
-
domain_remove.add_element "domain:status", {"s" => options[:remove_status]}
|
72
|
-
end
|
73
|
-
|
74
|
-
if options[:remove_tech]
|
75
|
-
domain_contact = domain_remove.add_element "domain:contact", {"type" => "tech"}
|
76
|
-
domain_contact.text = options[:remove_tech]
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
# <domain:chg>
|
81
|
-
if options[:auth_info]
|
82
|
-
domain_change = domain_update.add_element "domain:chg"
|
83
|
-
|
84
|
-
if options[:registrant]
|
85
|
-
domain_registrant = domain_change.add_element "domain:registrant"
|
86
|
-
domain_registrant.text = options[:registrant]
|
87
|
-
end
|
88
|
-
|
89
|
-
domain_authinfo = domain_change.add_element "domain:authInfo"
|
90
|
-
|
91
|
-
domain_pw = domain_authinfo.add_element "domain:pw"
|
92
|
-
domain_pw.text = options[:auth_info]
|
93
|
-
end
|
94
|
-
|
95
|
-
if options[:restore]
|
96
|
-
command.add_element("extension").tap do |ext|
|
97
|
-
ext.add_element("rgp:update", {"xmlns:rgp"=>"urn:ietf:params:xml:ns:rgp-1.0",
|
98
|
-
"xsi:schemaLocation"=>"urn:ietf:params:xml:ns:rgp-1.0 rgp-1.0.xsd"}).
|
99
|
-
add_element("rgp:restore", {"op"=> "request"})
|
100
|
-
end
|
101
|
-
end
|
102
|
-
# TODO: Registrant
|
103
|
-
end
|
104
|
-
end
|
data/lib/epp/epp_command.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
include REXML
|
2
|
-
|
3
|
-
class KonoEppCommand < REXML::Document
|
4
|
-
def initialize( source = nil, context = nil )
|
5
|
-
super( source, context )
|
6
|
-
|
7
|
-
add( XMLDecl.new( "1.0", "UTF-8", "no" ) )
|
8
|
-
|
9
|
-
epp = add_element( "epp", { "xmlns" => "urn:ietf:params:xml:ns:epp-1.0",
|
10
|
-
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
|
11
|
-
"xsi:schemaLocation" => "urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd" } )
|
12
|
-
|
13
|
-
epp.add_element( "command" )
|
14
|
-
end
|
15
|
-
end
|
data/lib/epp/exceptions.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
class KonoEppErrorResponse < StandardError #:nodoc:
|
2
|
-
attr_accessor :response_xml, :response_code, :reason_code, :message
|
3
|
-
|
4
|
-
# Generic EPP exception. Accepts a response code and a message
|
5
|
-
def initialize(attributes = {})
|
6
|
-
@response_xml = attributes[:xml]
|
7
|
-
@response_code = attributes[:response_code]
|
8
|
-
@reason_code = attributes[:reason_code]
|
9
|
-
@message = attributes[:message]
|
10
|
-
end
|
11
|
-
|
12
|
-
def to_s
|
13
|
-
"#{@message} (reason: #{@reason_code} code: #{@response_code})"
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
class KonoEppAuthenticationPasswordExpired < KonoEppErrorResponse ; end
|
18
|
-
class KonoEppLoginNeeded < KonoEppErrorResponse ; end
|
19
|
-
|
20
|
-
##
|
21
|
-
# Errore NIC:
|
22
|
-
# 2304=Object status prohibits operation 9022=Domain has status clientTransferProhibited
|
23
|
-
class KonoEppDomainHasStatusCliTransProhibited < KonoEppErrorResponse; end
|
24
|
-
|
25
|
-
##
|
26
|
-
# Errore NIC:
|
27
|
-
# 2304=Object status prohibits operation 9026=Domain has status clientUpdateProhibited
|
28
|
-
class KonoEppDomainHasStatusClientUpdateProhibited < KonoEppErrorResponse; end
|
data/lib/epp/server.rb
DELETED
@@ -1,295 +0,0 @@
|
|
1
|
-
module KonoEppClient #:nodoc:
|
2
|
-
class Server
|
3
|
-
include REXML
|
4
|
-
include RequiresParameters
|
5
|
-
|
6
|
-
require 'nokogiri'
|
7
|
-
|
8
|
-
attr_accessor :tag, :password, :server, :port, :ssl_version, :old_server, :services, :lang, :extensions, :version, :credit, :timeout
|
9
|
-
|
10
|
-
# ==== Required Attrbiutes
|
11
|
-
#
|
12
|
-
# * <tt>:server</tt> - The EPP server to connect to
|
13
|
-
# * <tt>:tag</tt> - The tag or username used with <tt><login></tt> requests.
|
14
|
-
# * <tt>:password</tt> - The password used with <tt><login></tt> requests.
|
15
|
-
#
|
16
|
-
# ==== Optional Attributes
|
17
|
-
#
|
18
|
-
# * <tt>:port</tt> - The EPP standard port is 700. However, you can choose a different port to use.
|
19
|
-
# * <tt>:clTRID</tt> - The client transaction identifier is an element that EPP specifies MAY be used to uniquely identify the command to the server. You are responsible for maintaining your own transaction identifier space to ensure uniqueness. Defaults to "ABC-12345"
|
20
|
-
# * <tt>:old_server</tt> - Set to true to read and write frames in a way that is compatible with older EPP servers. Default is false.
|
21
|
-
# * <tt>:lang</tt> - Set custom language attribute. Default is 'en'.
|
22
|
-
# * <tt>:services</tt> - Use custom EPP services in the <login> frame. The defaults use the EPP standard domain, contact and host 1.0 services.
|
23
|
-
# * <tt>:extensions</tt> - URLs to custom extensions to standard EPP. Use these to extend the standard EPP (e.g., Nominet uses extensions). Defaults to none.
|
24
|
-
# * <tt>:version</tt> - Set the EPP version. Defaults to "1.0".
|
25
|
-
# * <tt>:transport</tt> - Type of connection (http or tcp). Default to "tcp"
|
26
|
-
# * <tt>:timeout</tt> - Timeou for connections in seconds. Default to "30"
|
27
|
-
# * <tt>:ssl_version</tt> - Version of the ssl protocol versione. Default to TLSv1
|
28
|
-
# * <tt>:ssl_version</tt> - Version of the ssl protocol versione. Default to TLSv1
|
29
|
-
#
|
30
|
-
def initialize(attributes = {})
|
31
|
-
requires!(attributes, :tag, :password, :server)
|
32
|
-
|
33
|
-
@tag = attributes[:tag]
|
34
|
-
@password = attributes[:password]
|
35
|
-
@server = attributes[:server]
|
36
|
-
@port = attributes[:port] || 700
|
37
|
-
@old_server = attributes[:old_server] || false
|
38
|
-
@lang = attributes[:lang] || "en"
|
39
|
-
@services = attributes[:services] || ["urn:ietf:params:xml:ns:domain-1.0", "urn:ietf:params:xml:ns:contact-1.0", "urn:ietf:params:xml:ns:host-1.0"]
|
40
|
-
@extensions = attributes[:extensions] || []
|
41
|
-
@version = attributes[:version] || "1.0"
|
42
|
-
@transport = attributes[:transport] || :tcp
|
43
|
-
@timeout = attributes[:timeout] || 30
|
44
|
-
@ssl_version = attributes[:ssl_version] || :TLSv1
|
45
|
-
|
46
|
-
@logged_in = false
|
47
|
-
end
|
48
|
-
|
49
|
-
def connect_and_hello
|
50
|
-
open_connection
|
51
|
-
|
52
|
-
hello
|
53
|
-
end
|
54
|
-
|
55
|
-
# Closes the connection to the EPP server.
|
56
|
-
def close_connection
|
57
|
-
@connection.close
|
58
|
-
end
|
59
|
-
|
60
|
-
# Sends an XML request to the EPP server, and receives an XML response.
|
61
|
-
# <tt><login></tt> and <tt><logout></tt> requests are also wrapped
|
62
|
-
# around the request, so we can close the socket immediately after
|
63
|
-
# the request is made.
|
64
|
-
def request( xml )
|
65
|
-
# open_connection
|
66
|
-
|
67
|
-
# @logged_in = true if login
|
68
|
-
|
69
|
-
begin
|
70
|
-
@response = send_request( xml )
|
71
|
-
ensure
|
72
|
-
if @logged_in && !old_server
|
73
|
-
@logged_in = false if logout
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
return @response
|
78
|
-
end
|
79
|
-
|
80
|
-
# Sends a standard login request to the EPP server.
|
81
|
-
def login
|
82
|
-
login = KonoEppLogin.new( tag, password )
|
83
|
-
|
84
|
-
# FIXME: Order matters
|
85
|
-
login.version = version
|
86
|
-
login.lang = lang
|
87
|
-
|
88
|
-
login.services = services
|
89
|
-
login.extensions = extensions
|
90
|
-
|
91
|
-
send_command( login )
|
92
|
-
end
|
93
|
-
|
94
|
-
def change_password( new_password )
|
95
|
-
login = KonoEppLogin.new( tag, password )
|
96
|
-
|
97
|
-
# FIXME: Order matters
|
98
|
-
login.new_password = new_password
|
99
|
-
|
100
|
-
login.version = version
|
101
|
-
login.lang = lang
|
102
|
-
|
103
|
-
login.services = services
|
104
|
-
login.extensions = extensions
|
105
|
-
|
106
|
-
send_command( login )
|
107
|
-
end
|
108
|
-
|
109
|
-
def logged_in?
|
110
|
-
begin
|
111
|
-
poll
|
112
|
-
rescue
|
113
|
-
return false
|
114
|
-
end
|
115
|
-
|
116
|
-
return true
|
117
|
-
end
|
118
|
-
|
119
|
-
# FIXME: Remove command wrappers?
|
120
|
-
def hello
|
121
|
-
send_request( KonoEppHello.new.to_s )
|
122
|
-
end
|
123
|
-
|
124
|
-
def poll( id = nil )
|
125
|
-
poll = KonoEppPoll.new( id ? :ack : :req )
|
126
|
-
|
127
|
-
poll.ack_id = id if id
|
128
|
-
|
129
|
-
send_command( poll )
|
130
|
-
end
|
131
|
-
|
132
|
-
def create_contact( options )
|
133
|
-
contact = KonoEppCreateContact.new options
|
134
|
-
send_command( contact )
|
135
|
-
end
|
136
|
-
|
137
|
-
def check_contacts(ids)
|
138
|
-
send_command( KonoEppCheckContacts.new(ids) )
|
139
|
-
end
|
140
|
-
|
141
|
-
def delete_contact( id )
|
142
|
-
contact = KonoEppDeleteContact.new id
|
143
|
-
send_command( contact )
|
144
|
-
end
|
145
|
-
|
146
|
-
def update_contact( options )
|
147
|
-
contact = KonoEppUpdateContact.new options
|
148
|
-
send_command( contact )
|
149
|
-
end
|
150
|
-
|
151
|
-
def create_domain( options )
|
152
|
-
domain = KonoEppCreateDomain.new options
|
153
|
-
send_command( domain )
|
154
|
-
end
|
155
|
-
|
156
|
-
def check_domains( *domains )
|
157
|
-
send_command( KonoEppCheckDomains.new *domains )
|
158
|
-
end
|
159
|
-
|
160
|
-
def update_domain( options )
|
161
|
-
domain = KonoEppUpdateDomain.new options
|
162
|
-
send_command( domain )
|
163
|
-
end
|
164
|
-
|
165
|
-
def delete_domain( name )
|
166
|
-
domain = KonoEppDeleteDomain.new name
|
167
|
-
send_command( domain )
|
168
|
-
end
|
169
|
-
|
170
|
-
def info_contact( id )
|
171
|
-
contact = KonoEppInfoContact.new id
|
172
|
-
send_command( contact )
|
173
|
-
end
|
174
|
-
|
175
|
-
def info_domain( name )
|
176
|
-
info = KonoEppInfoDomain.new name
|
177
|
-
send_command( info )
|
178
|
-
end
|
179
|
-
|
180
|
-
def transfer_domain(name, authinfo, op, extension: nil)
|
181
|
-
send_command(KonoEppTransferDomain.new( name, authinfo, op, extension: extension))
|
182
|
-
end
|
183
|
-
|
184
|
-
# Sends a standard logout request to the EPP server.
|
185
|
-
def logout
|
186
|
-
send_command( KonoEppLogout.new, 1500 )
|
187
|
-
end
|
188
|
-
|
189
|
-
# private
|
190
|
-
# Wrapper which sends XML to the server, and receives
|
191
|
-
# the response in return.
|
192
|
-
def send_request( xml )
|
193
|
-
write( xml )
|
194
|
-
read
|
195
|
-
end
|
196
|
-
|
197
|
-
def send_command( command, expected_result = 1000..1999 )
|
198
|
-
namespaces = { 'extepp' => 'http://www.nic.it/ITNIC-EPP/extepp-2.0',
|
199
|
-
'xmlns' => "urn:ietf:params:xml:ns:epp-1.0" }
|
200
|
-
|
201
|
-
xml = Nokogiri.XML( send_request( command.to_s ) )
|
202
|
-
|
203
|
-
# TODO: multiple <response> RFC 3730 §2.6
|
204
|
-
result = xml.at_xpath( "/xmlns:epp/xmlns:response[1]/xmlns:result",
|
205
|
-
namespaces )
|
206
|
-
raise KonoEppErrorResponse.new( :message => 'Malformed response' ) if result.nil?
|
207
|
-
|
208
|
-
xmlns_code = result.at_xpath( "@code" )
|
209
|
-
raise KonoEppErrorResponse.new( :message => 'Malformed response' ) if xmlns_code.nil?
|
210
|
-
|
211
|
-
response_code = xmlns_code.value.to_i
|
212
|
-
|
213
|
-
xmlns_msg = result.xpath( "xmlns:msg/text ()",
|
214
|
-
namespaces )
|
215
|
-
raise KonoEppErrorResponse.new( :message => 'Malformed response' ) if xmlns_msg.empty?
|
216
|
-
|
217
|
-
result_message = xmlns_msg.text.strip
|
218
|
-
|
219
|
-
# TODO: value
|
220
|
-
|
221
|
-
xmlns_ext_reason = result.xpath( "xmlns:extValue/xmlns:reason",
|
222
|
-
namespaces)
|
223
|
-
result_message += ": #{xmlns_ext_reason.text.strip}" unless xmlns_ext_reason.empty?
|
224
|
-
|
225
|
-
xmlns_reason_code = result.xpath( "xmlns:extValue/xmlns:value/extepp:reasonCode",
|
226
|
-
namespaces )
|
227
|
-
reason_code = xmlns_reason_code.text.strip.to_i unless xmlns_reason_code.empty?
|
228
|
-
|
229
|
-
credit_msg = xml.xpath( "//extepp:credit/text ()",
|
230
|
-
namespaces )
|
231
|
-
@credit = credit_msg.text.to_f unless credit_msg.empty?
|
232
|
-
|
233
|
-
if expected_result === response_code
|
234
|
-
return xml
|
235
|
-
end
|
236
|
-
|
237
|
-
args = { :xml => xml,
|
238
|
-
:response_code => response_code,
|
239
|
-
:reason_code => reason_code,
|
240
|
-
:message => result_message }
|
241
|
-
|
242
|
-
case [ response_code, reason_code ]
|
243
|
-
when [2200, 6004]
|
244
|
-
raise KonoEppAuthenticationPasswordExpired.new( args )
|
245
|
-
when [2002, 4015]
|
246
|
-
raise KonoEppLoginNeeded.new( args )
|
247
|
-
when [2304, 9022]
|
248
|
-
raise KonoEppDomainHasStatusCliTransProhibited.new(args)
|
249
|
-
when [2304, 9026]
|
250
|
-
raise KonoEppDomainHasStatusClientUpdateProhibited.new(args)
|
251
|
-
else
|
252
|
-
raise KonoEppErrorResponse.new( args )
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
|
-
# Establishes the connection to the server. If the connection is
|
257
|
-
# established, then this method will call read and return
|
258
|
-
# the EPP <tt><greeting></tt> which is sent by the
|
259
|
-
# server upon connection.
|
260
|
-
def open_connection
|
261
|
-
# FIXME il timeout serve solamente nella versione tcp
|
262
|
-
# FIXME perchè utilizzare un'istanza di classe? non sarebbe meglio avere un metodo che genera il transport
|
263
|
-
# e successivamente viene utilizzato sempre quello?
|
264
|
-
Timeout.timeout @timeout do
|
265
|
-
case @transport
|
266
|
-
when :tcp
|
267
|
-
@connection = KonoEppClient::Transport::TcpTransport.new(server, port)
|
268
|
-
when :http
|
269
|
-
@connection = KonoEppClient::Transport::HttpTransport.new(server, port,
|
270
|
-
ssl_version: ssl_version,
|
271
|
-
cookie_file: "#{@tag.downcase}.cookies.pstore"
|
272
|
-
)
|
273
|
-
end
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
# Receive an EPP response from the server. Since the connection is blocking,
|
278
|
-
# this method will wait until the connection becomes available for use. If
|
279
|
-
# the connection is broken, a SocketError will be raised. Otherwise,
|
280
|
-
# it will return a string containing the XML from the server.
|
281
|
-
def read
|
282
|
-
Timeout.timeout @timeout do
|
283
|
-
@connection.read
|
284
|
-
end
|
285
|
-
end
|
286
|
-
|
287
|
-
# Send XML to the server. If the socket returns EOF,
|
288
|
-
# the connection has closed and a SocketError is raised.
|
289
|
-
def write( xml )
|
290
|
-
Timeout.timeout @timeout do
|
291
|
-
@connection.write( xml )
|
292
|
-
end
|
293
|
-
end
|
294
|
-
end
|
295
|
-
end
|
data/lib/epp/transport/tcp.rb
DELETED
@@ -1,93 +0,0 @@
|
|
1
|
-
module KonoEppClient::Transport
|
2
|
-
class TcpTransport
|
3
|
-
include KonoEppClient::Transport
|
4
|
-
|
5
|
-
def initialize( server, port )
|
6
|
-
@connection = TCPSocket.new( server, port )
|
7
|
-
@socket = OpenSSL::SSL::SSLSocket.new( @connection )
|
8
|
-
|
9
|
-
# Synchronously close the connection & socket
|
10
|
-
@socket.sync_close
|
11
|
-
|
12
|
-
# Connect
|
13
|
-
@socket.connect
|
14
|
-
|
15
|
-
# Get the initial frame
|
16
|
-
read
|
17
|
-
end
|
18
|
-
|
19
|
-
def read
|
20
|
-
if old_server
|
21
|
-
data = ""
|
22
|
-
first_char = @socket.read(1)
|
23
|
-
|
24
|
-
if first_char.nil? and @socket.eof?
|
25
|
-
raise SocketError.new("Connection closed by remote server")
|
26
|
-
elsif first_char.nil?
|
27
|
-
raise SocketError.new("Error reading frame from remote server")
|
28
|
-
else
|
29
|
-
data << first_char
|
30
|
-
|
31
|
-
while char = @socket.read(1)
|
32
|
-
data << char
|
33
|
-
|
34
|
-
return data if data =~ %r|<\/epp>\n$|mi # at end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
else
|
38
|
-
header = @socket.read(4)
|
39
|
-
|
40
|
-
if header.nil? and @socket.eof?
|
41
|
-
raise SocketError.new("Connection closed by remote server")
|
42
|
-
elsif header.nil?
|
43
|
-
raise SocketError.new("Error reading frame from remote server")
|
44
|
-
else
|
45
|
-
unpacked_header = header.unpack("N")
|
46
|
-
length = unpacked_header[0]
|
47
|
-
|
48
|
-
if length < 5
|
49
|
-
raise SocketError.new("Got bad frame header length of #{length} bytes from the server")
|
50
|
-
else
|
51
|
-
response = @socket.read(length - 4)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def write
|
58
|
-
if defined?( @socket ) and @socket.is_a?( OpenSSL::SSL::SSLSocket )
|
59
|
-
@socket.close
|
60
|
-
@socket = nil
|
61
|
-
end
|
62
|
-
|
63
|
-
if defined?( @connection ) and @connection.is_a?( TCPSocket )
|
64
|
-
@connection.close
|
65
|
-
@connection = nil
|
66
|
-
end
|
67
|
-
|
68
|
-
return true if @connection.nil? and @socket.nil?
|
69
|
-
end
|
70
|
-
|
71
|
-
def close
|
72
|
-
if defined?( @socket ) and @socket.is_a?( OpenSSL::SSL::SSLSocket )
|
73
|
-
@socket.close
|
74
|
-
@socket = nil
|
75
|
-
end
|
76
|
-
|
77
|
-
if defined?( @connection ) and @connection.is_a?( TCPSocket )
|
78
|
-
@connection.close
|
79
|
-
@connection = nil
|
80
|
-
end
|
81
|
-
|
82
|
-
return true if @connection.nil? and @socket.nil?
|
83
|
-
end
|
84
|
-
private
|
85
|
-
# Receive an EPP frame from the server. Since the connection is blocking,
|
86
|
-
# this method will wait until the connection becomes available for use. If
|
87
|
-
# the connection is broken, a SocketError will be raised. Otherwise,
|
88
|
-
# it will return a string containing the XML from the server.
|
89
|
-
def get_frame
|
90
|
-
end
|
91
|
-
|
92
|
-
end
|
93
|
-
end
|