Merge branch 'master' of github.com:domify/registry

This commit is contained in:
Priit Tark 2015-05-31 23:28:42 +03:00
commit f1ebedc234
16 changed files with 2049 additions and 180 deletions

View file

@ -68,7 +68,7 @@ gem 'digidoc_client', '~> 0.2.1'
# epp # epp
gem 'epp', '~> 1.4.2', github: 'gitlabeu/epp' gem 'epp', '~> 1.4.2', github: 'gitlabeu/epp'
gem 'epp-xml', '~> 0.10.4' # EPP XMLs gem 'epp-xml', '~> 1.0.1' # EPP XMLs
gem 'uuidtools', '~> 2.1.4' # For unique IDs (used by the epp gem) gem 'uuidtools', '~> 2.1.4' # For unique IDs (used by the epp gem)
# for importing legacy db # for importing legacy db

View file

@ -161,7 +161,7 @@ GEM
nokogiri (>= 1.4.0) nokogiri (>= 1.4.0)
savon (>= 2.4.0) savon (>= 2.4.0)
docile (1.1.5) docile (1.1.5)
epp-xml (0.10.4) epp-xml (1.0.1)
activesupport (~> 4.1) activesupport (~> 4.1)
builder (~> 3.2) builder (~> 3.2)
equalizer (0.0.11) equalizer (0.0.11)
@ -512,7 +512,7 @@ DEPENDENCIES
devise (~> 3.4.1) devise (~> 3.4.1)
digidoc_client (~> 0.2.1) digidoc_client (~> 0.2.1)
epp (~> 1.4.2)! epp (~> 1.4.2)!
epp-xml (~> 0.10.4) epp-xml (~> 1.0.1)
fabrication (~> 2.12.2) fabrication (~> 2.12.2)
faker (~> 1.3.0) faker (~> 1.3.0)
figaro (~> 1.1.0) figaro (~> 1.1.0)

View file

@ -155,6 +155,10 @@ class Domain < ActiveRecord::Base
self[:name_dirty] = value self[:name_dirty] = value
end end
def roid
"EIS-#{id}"
end
def registrant_typeahead def registrant_typeahead
@registrant_typeahead || registrant.try(:name) || nil @registrant_typeahead || registrant.try(:name) || nil
end end
@ -250,7 +254,7 @@ class Domain < ActiveRecord::Base
def validate_period def validate_period
return unless period.present? return unless period.present?
if period_unit == 'd' if period_unit == 'd'
valid_values = %w(365 366 710 712 1065 1068) valid_values = %w(365 730 1095)
elsif period_unit == 'm' elsif period_unit == 'm'
valid_values = %w(12 24 36) valid_values = %w(12 24 36)
else else

View file

@ -7,6 +7,7 @@ xml.epp_head do
xml.resData do xml.resData do
xml.tag!('domain:infData', 'xmlns:domain' => 'urn:ietf:params:xml:ns:domain-1.0') do xml.tag!('domain:infData', 'xmlns:domain' => 'urn:ietf:params:xml:ns:domain-1.0') do
xml.tag!('domain:name', @domain.name) xml.tag!('domain:name', @domain.name)
xml.tag!('domain:roid', @domain.roid)
@domain.domain_statuses.each do |ds| @domain.domain_statuses.each do |ds|
xml.tag!('domain:status', ds.description, 's' => ds.value) unless ds.description.blank? xml.tag!('domain:status', ds.description, 's' => ds.value) unless ds.description.blank?
xml.tag!('domain:status', 's' => ds.value) if ds.description.blank? xml.tag!('domain:status', 's' => ds.value) if ds.description.blank?
@ -38,17 +39,17 @@ xml.epp_head do
xml.tag!('domain:clID', @domain.registrar_name) xml.tag!('domain:clID', @domain.registrar_name)
xml.tag!('domain:crID', @domain.creator.try(:registrar)) xml.tag!('domain:crID', @domain.creator.try(:registrar)) if @domain.creator
xml.tag!('domain:crDate', @domain.created_at.try(:iso8601)) xml.tag!('domain:crDate', @domain.created_at.try(:iso8601))
xml.tag!('domain:upDate', @domain.updated_at.try(:iso8601)) if @domain.updated_at != @domain.created_at
xml.tag!('domain:exDate', @domain.valid_to.try(:iso8601)) xml.tag!('domain:exDate', @domain.valid_to.try(:iso8601))
# TODO Make domain stampable # TODO Make domain stampable
#xml.tag!('domain:upID', @domain.updated_by) #xml.tag!('domain:upID', @domain.updated_by)
xml.tag!('domain:upDate', @domain.updated_at.try(:iso8601)) if @domain.updated_at != @domain.created_at
# TODO Make domain transferrable # TODO Make domain transferrable
#xml.tag!('domain:trDate', @domain.transferred_at) if @domain.transferred_at #xml.tag!('domain:trDate', @domain.transferred_at) if @domain.transferred_at

408
doc/schemas/contact-1.0.xsd Normal file
View file

@ -0,0 +1,408 @@
<?xml version="1.0" encoding="UTF-8"?>
<schema targetNamespace="urn:ietf:params:xml:ns:contact-1.0"
xmlns:contact="urn:ietf:params:xml:ns:contact-1.0"
xmlns:epp="urn:ietf:params:xml:ns:epp-1.0"
xmlns:eppcom="urn:ietf:params:xml:ns:eppcom-1.0"
xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<!--
Import common element types.
-->
<import namespace="urn:ietf:params:xml:ns:eppcom-1.0" schemaLocation="doc/schemas/eppcom-1.0.xsd"/>
<import namespace="urn:ietf:params:xml:ns:epp-1.0" schemaLocation="doc/schemas/epp-1.0.xsd"/>
<annotation>
<documentation>
Extensible Provisioning Protocol v1.0
contact provisioning schema.
</documentation>
</annotation>
<!--
Child elements found in EPP commands.
-->
<element name="check" type="contact:mIDType"/>
<element name="create" type="contact:createType"/>
<element name="delete" type="contact:sIDType"/>
<element name="info" type="contact:authIDType"/>
<element name="transfer" type="contact:authIDType"/>
<element name="update" type="contact:updateType"/>
<!--
Utility types.
-->
<simpleType name="ccType">
<restriction base="token">
<length value="2"/>
</restriction>
</simpleType>
<complexType name="e164Type">
<simpleContent>
<extension base="contact:e164StringType">
<attribute name="x" type="token"/>
</extension>
</simpleContent>
</complexType>
<simpleType name="e164StringType">
<restriction base="token">
<!--<pattern value="(\+[0-9]{1,3}\.[0-9]{1,14})?"/> -->
<maxLength value="17"/>
</restriction>
</simpleType>
<simpleType name="pcType">
<restriction base="token">
<maxLength value="16"/>
</restriction>
</simpleType>
<simpleType name="postalLineType">
<restriction base="normalizedString">
<minLength value="1"/>
<maxLength value="255"/>
</restriction>
</simpleType>
<simpleType name="optPostalLineType">
<restriction base="normalizedString">
<maxLength value="255"/>
</restriction>
</simpleType>
<complexType name="identType">
<simpleContent>
<extension base="eppcom:clIDType">
<attribute name="type" type="contact:identAttrType"/>
</extension>
</simpleContent>
</complexType>
<simpleType name="identAttrType">
<restriction base="token">
<enumeration value="ico"/>
<enumeration value="op"/>
<enumeration value="passport"/>
<enumeration value="birthday"/>
</restriction>
</simpleType>
<!--
Child elements of the <create> command.
-->
<complexType name="createType">
<sequence>
<element name="id" type="eppcom:clIDType"/>
<element name="postalInfo" type="contact:postalInfoType"
maxOccurs="2"/>
<element name="voice" type="contact:e164Type"
minOccurs="0"/>
<element name="fax" type="contact:e164Type"
minOccurs="0"/>
<element name="email" type="eppcom:minTokenType"/>
<element name="ident" type="contact:identType"
minOccurs="0"/>
<element name="authInfo" type="contact:authInfoType"/>
<element name="disclose" type="contact:discloseType"
minOccurs="0"/>
</sequence>
</complexType>
<complexType name="postalInfoType">
<sequence>
<element name="name" type="contact:postalLineType"/>
<element name="org" type="contact:optPostalLineType"
minOccurs="0"/>
<element name="addr" type="contact:addrType"/>
</sequence>
<attribute name="type" type="contact:postalInfoEnumType"
use="required"/>
</complexType>
<simpleType name="postalInfoEnumType">
<restriction base="token">
<enumeration value="loc"/>
<enumeration value="int"/>
</restriction>
</simpleType>
<complexType name="addrType">
<sequence>
<element name="street" type="contact:optPostalLineType"
minOccurs="0" maxOccurs="3"/>
<element name="city" type="contact:postalLineType"/>
<element name="sp" type="contact:optPostalLineType"
minOccurs="0"/>
<element name="pc" type="contact:pcType"
minOccurs="0"/>
<element name="cc" type="contact:ccType"/>
</sequence>
</complexType>
<complexType name="authInfoType">
<choice>
<element name="pw" type="eppcom:pwAuthInfoType"/>
<element name="ext" type="eppcom:extAuthInfoType"/>
</choice>
</complexType>
<complexType name="discloseType">
<sequence>
<element name="name" type="contact:intLocType"
minOccurs="0" maxOccurs="2"/>
<element name="org" type="contact:intLocType"
minOccurs="0" maxOccurs="2"/>
<element name="addr" type="contact:intLocType"
minOccurs="0" maxOccurs="2"/>
<element name="voice" minOccurs="0"/>
<element name="fax" minOccurs="0"/>
<element name="email" minOccurs="0"/>
</sequence>
<attribute name="flag" type="boolean" use="required"/>
</complexType>
<complexType name="intLocType">
<attribute name="type" type="contact:postalInfoEnumType"
use="required"/>
</complexType>
<!--
Child element of commands that require only an identifier.
-->
<complexType name="sIDType">
<sequence>
<element name="id" type="eppcom:clIDType"/>
</sequence>
</complexType>
<!--
Child element of commands that accept multiple identifiers.
-->
<complexType name="mIDType">
<sequence>
<element name="id" type="eppcom:clIDType"
maxOccurs="unbounded"/>
</sequence>
</complexType>
<!--
Child elements of the <info> and <transfer> commands.
-->
<complexType name="authIDType">
<sequence>
<element name="id" type="eppcom:clIDType"/>
<element name="authInfo" type="contact:authInfoType"
minOccurs="0"/>
</sequence>
</complexType>
<!--
Child elements of the <update> command.
-->
<complexType name="updateType">
<sequence>
<element name="id" type="eppcom:clIDType"/>
<element name="add" type="contact:addRemType"
minOccurs="0"/>
<element name="rem" type="contact:addRemType"
minOccurs="0"/>
<element name="chg" type="contact:chgType"
minOccurs="0"/>
</sequence>
</complexType>
<!--
Data elements that can be added or removed.
-->
<complexType name="addRemType">
<sequence>
<element name="status" type="contact:statusType"
maxOccurs="7"/>
</sequence>
</complexType>
<!--
Data elements that can be changed.
-->
<complexType name="chgType">
<sequence>
<element name="postalInfo" type="contact:chgPostalInfoType"
minOccurs="0" maxOccurs="2"/>
<element name="voice" type="contact:e164Type"
minOccurs="0"/>
<element name="fax" type="contact:e164Type"
minOccurs="0"/>
<element name="email" type="eppcom:minTokenType"
minOccurs="0"/>
<element name="ident" type="contact:identType"
minOccurs="0"/>
<element name="authInfo" type="contact:authInfoType"
minOccurs="0"/>
<element name="disclose" type="contact:discloseType"
minOccurs="0"/>
</sequence>
</complexType>
<complexType name="chgPostalInfoType">
<sequence>
<element name="name" type="contact:postalLineType"
minOccurs="0"/>
<element name="org" type="contact:optPostalLineType"
minOccurs="0"/>
<element name="addr" type="contact:addrType"
minOccurs="0"/>
</sequence>
<attribute name="type" type="contact:postalInfoEnumType"
use="required"/>
</complexType>
<!--
Child response elements.
-->
<element name="chkData" type="contact:chkDataType"/>
<element name="creData" type="contact:creDataType"/>
<element name="infData" type="contact:infDataType"/>
<element name="panData" type="contact:panDataType"/>
<element name="trnData" type="contact:trnDataType"/>
<!--
<check> response elements.
-->
<complexType name="chkDataType">
<sequence>
<element name="cd" type="contact:checkType"
maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="checkType">
<sequence>
<element name="id" type="contact:checkIDType"/>
<element name="reason" type="eppcom:reasonType"
minOccurs="0"/>
</sequence>
</complexType>
<complexType name="checkIDType">
<simpleContent>
<extension base="eppcom:clIDType">
<attribute name="avail" type="boolean"
use="required"/>
</extension>
</simpleContent>
</complexType>
<!--
<create> response elements.
-->
<complexType name="creDataType">
<sequence>
<element name="id" type="eppcom:clIDType"/>
<element name="crDate" type="dateTime"/>
</sequence>
</complexType>
<!--
<info> response elements.
-->
<complexType name="infDataType">
<sequence>
<element name="id" type="eppcom:clIDType"/>
<element name="roid" type="eppcom:roidType"/>
<element name="status" type="contact:statusType"
maxOccurs="7"/>
<element name="postalInfo" type="contact:postalInfoType"
maxOccurs="2"/>
<element name="voice" type="contact:e164Type"
minOccurs="0"/>
<element name="fax" type="contact:e164Type"
minOccurs="0"/>
<element name="email" type="eppcom:minTokenType"/>
<element name="clID" type="eppcom:clIDType"/>
<element name="crID" type="eppcom:clIDType"/>
<element name="crDate" type="dateTime"/>
<element name="upID" type="eppcom:clIDType"
minOccurs="0"/>
<element name="upDate" type="dateTime"
minOccurs="0"/>
<element name="trDate" type="dateTime"
minOccurs="0"/>
<element name="authInfo" type="contact:authInfoType"
minOccurs="0"/>
<element name="disclose" type="contact:discloseType"
minOccurs="0"/>
</sequence>
</complexType>
<!--
Status is a combination of attributes and an optional human-readable
message that may be expressed in languages other than English.
-->
<complexType name="statusType">
<simpleContent>
<extension base="normalizedString">
<attribute name="s" type="contact:statusValueType"
use="required"/>
<attribute name="lang" type="language"
default="en"/>
</extension>
</simpleContent>
</complexType>
<simpleType name="statusValueType">
<restriction base="token">
<enumeration value="clientDeleteProhibited"/>
<enumeration value="clientTransferProhibited"/>
<enumeration value="clientUpdateProhibited"/>
<enumeration value="linked"/>
<enumeration value="ok"/>
<enumeration value="pendingCreate"/>
<enumeration value="pendingDelete"/>
<enumeration value="pendingTransfer"/>
<enumeration value="pendingUpdate"/>
<enumeration value="serverDeleteProhibited"/>
<enumeration value="serverTransferProhibited"/>
<enumeration value="serverUpdateProhibited"/>
</restriction>
</simpleType>
<!--
Pending action notification response elements.
-->
<complexType name="panDataType">
<sequence>
<element name="id" type="contact:paCLIDType"/>
<element name="paTRID" type="epp:trIDType"/>
<element name="paDate" type="dateTime"/>
</sequence>
</complexType>
<complexType name="paCLIDType">
<simpleContent>
<extension base="eppcom:clIDType">
<attribute name="paResult" type="boolean"
use="required"/>
</extension>
</simpleContent>
</complexType>
<!--
<transfer> response elements.
-->
<complexType name="trnDataType">
<sequence>
<element name="id" type="eppcom:clIDType"/>
<element name="trStatus" type="eppcom:trStatusType"/>
<element name="reID" type="eppcom:clIDType"/>
<element name="reDate" type="dateTime"/>
<element name="acID" type="eppcom:clIDType"/>
<element name="acDate" type="dateTime"/>
</sequence>
</complexType>
<!--
End of schema.
-->
</schema>

451
doc/schemas/domain-1.0.xsd Normal file
View file

@ -0,0 +1,451 @@
<?xml version="1.0" encoding="UTF-8"?>
<schema targetNamespace="urn:ietf:params:xml:ns:domain-1.0"
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0"
xmlns:host="urn:ietf:params:xml:ns:host-1.0"
xmlns:epp="urn:ietf:params:xml:ns:epp-1.0"
xmlns:eppcom="urn:ietf:params:xml:ns:eppcom-1.0"
xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<!--
Import common element types.
-->
<import namespace="urn:ietf:params:xml:ns:eppcom-1.0" schemaLocation="doc/schemas/eppcom-1.0.xsd"/>
<import namespace="urn:ietf:params:xml:ns:epp-1.0" schemaLocation="doc/schemas/epp-1.0.xsd"/>
<import namespace="urn:ietf:params:xml:ns:host-1.0" schemaLocation="doc/schemas/host-1.0.xsd"/>
<import namespace="urn:ietf:params:xml:ns:secDNS-1.1" schemaLocation="doc/schemas/secDNS-1.1.xsd"/>
<import namespace="urn:ietf:params:xml:ns:eis-1.0" schemaLocation="doc/schemas/eis-1.0.xsd"/>
<annotation>
<documentation>
Extensible Provisioning Protocol v1.0
domain provisioning schema.
</documentation>
</annotation>
<!--
Child elements found in EPP commands.
-->
<element name="check" type="domain:mNameType"/>
<element name="create" type="domain:createType"/>
<element name="delete" type="domain:sNameType"/>
<element name="info" type="domain:infoType"/>
<element name="renew" type="domain:renewType"/>
<element name="transfer" type="domain:transferType"/>
<element name="update" type="domain:updateType"/>
<!--
Child elements of the <create> command.
-->
<complexType name="createType">
<sequence>
<element name="name" type="eppcom:labelType"/>
<element name="period" type="domain:periodType"
minOccurs="0"/>
<element name="ns" type="domain:nsType"
minOccurs="0"/>
<element name="registrant" type="eppcom:clIDType"
minOccurs="0"/>
<element name="contact" type="domain:contactType"
minOccurs="0" maxOccurs="unbounded"/>
<element name="authInfo" type="domain:authInfoType" minOccurs="0"/>
</sequence>
</complexType>
<complexType name="periodType">
<simpleContent>
<extension base="domain:pLimitType">
<attribute name="unit" type="domain:pUnitType"
use="required"/>
</extension>
</simpleContent>
</complexType>
<simpleType name="pLimitType">
<restriction base="unsignedShort">
<minInclusive value="1"/>
<maxInclusive value="1095"/>
</restriction>
</simpleType>
<simpleType name="pUnitType">
<restriction base="token">
<enumeration value="y"/>
<enumeration value="m"/>
<enumeration value="d"/>
</restriction>
</simpleType>
<complexType name="nsType">
<choice>
<element name="hostObj" type="eppcom:labelType"
maxOccurs="unbounded"/>
<element name="hostAttr" type="domain:hostAttrType"
maxOccurs="unbounded"/>
</choice>
</complexType>
<!--
Name servers are either host objects or attributes.
-->
<complexType name="hostAttrType">
<sequence>
<element name="hostName" type="eppcom:labelType"/>
<element name="hostAddr" type="host:addrType"
minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
<!--
If attributes, addresses are optional and follow the
structure defined in the host mapping.
-->
<complexType name="contactType">
<simpleContent>
<extension base="eppcom:clIDType">
<attribute name="type" type="domain:contactAttrType"/>
</extension>
</simpleContent>
</complexType>
<simpleType name="contactAttrType">
<restriction base="token">
<enumeration value="admin"/>
<enumeration value="billing"/>
<enumeration value="tech"/>
</restriction>
</simpleType>
<complexType name="authInfoType">
<choice>
<element name="pw" type="eppcom:pwAuthInfoType"/>
<element name="ext" type="eppcom:extAuthInfoType"/>
</choice>
</complexType>
<!--
Child element of commands that require a single name.
-->
<complexType name="sNameType">
<sequence>
<element name="name" type="eppcom:labelType"/>
</sequence>
</complexType>
<!--
Child element of commands that accept multiple names.
-->
<complexType name="mNameType">
<sequence>
<element name="name" type="eppcom:labelType"
maxOccurs="unbounded"/>
</sequence>
</complexType>
<!--
Child elements of the <info> command.
-->
<complexType name="infoType">
<sequence>
<element name="name" type="domain:infoNameType"/>
<element name="authInfo" type="domain:authInfoType"
minOccurs="0"/>
</sequence>
</complexType>
<complexType name="infoNameType">
<simpleContent>
<extension base = "eppcom:labelType">
<attribute name="hosts" type="domain:hostsType"
default="all"/>
</extension>
</simpleContent>
</complexType>
<simpleType name="hostsType">
<restriction base="token">
<enumeration value="all"/>
<enumeration value="del"/>
<enumeration value="none"/>
<enumeration value="sub"/>
</restriction>
</simpleType>
<!--
Child elements of the <renew> command.
-->
<complexType name="renewType">
<sequence>
<element name="name" type="eppcom:labelType"/>
<element name="curExpDate" type="date"/>
<element name="period" type="domain:periodType"
minOccurs="0"/>
</sequence>
</complexType>
<!--
Child elements of the <transfer> command.
-->
<complexType name="transferType">
<sequence>
<element name="name" type="eppcom:labelType"/>
<element name="period" type="domain:periodType"
minOccurs="0"/>
<element name="authInfo" type="domain:authInfoType"
minOccurs="0"/>
</sequence>
</complexType>
<!--
Child elements of the <update> command.
-->
<complexType name="updateType">
<sequence>
<element name="name" type="eppcom:labelType"/>
<element name="add" type="domain:addRemType"
minOccurs="0"/>
<element name="rem" type="domain:addRemType"
minOccurs="0"/>
<element name="chg" type="domain:chgType"
minOccurs="0"/>
</sequence>
</complexType>
<!--
Data elements that can be added or removed.
-->
<complexType name="addRemType">
<sequence>
<element name="ns" type="domain:nsType"
minOccurs="0"/>
<element name="contact" type="domain:contactType"
minOccurs="0" maxOccurs="unbounded"/>
<element name="status" type="domain:statusType"
minOccurs="0" maxOccurs="11"/>
</sequence>
</complexType>
<!--
Data elements that can be changed.
-->
<complexType name="chgType">
<sequence>
<element name="registrant" type="domain:clIDChgType"
minOccurs="0"/>
<element name="authInfo" type="domain:authInfoChgType"
minOccurs="0"/>
</sequence>
</complexType>
<!--
Allow the registrant value to be nullified by changing the
minLength restriction to "0".
-->
<complexType name="clIDChgType">
<simpleContent>
<extension base="domain:clIDChgSimpleType">
<attribute name="verified" type="domain:verifiedType"/>
</extension>
</simpleContent>
</complexType>
<simpleType name="clIDChgSimpleType">
<restriction base="token">
<minLength value="0"/>
</restriction>
</simpleType>
<simpleType name="verifiedType">
<restriction base="token">
<enumeration value="yes"/>
<enumeration value="no"/>
</restriction>
</simpleType>
<!--
Allow the authInfo value to be nullified by including an
empty element within the choice.
-->
<complexType name="authInfoChgType">
<choice>
<element name="pw" type="eppcom:pwAuthInfoType"/>
<element name="ext" type="eppcom:extAuthInfoType"/>
<element name="null"/>
</choice>
</complexType>
<!--
Child response elements.
-->
<element name="chkData" type="domain:chkDataType"/>
<element name="creData" type="domain:creDataType"/>
<element name="infData" type="domain:infDataType"/>
<element name="panData" type="domain:panDataType"/>
<element name="renData" type="domain:renDataType"/>
<element name="trnData" type="domain:trnDataType"/>
<!--
<check> response elements.
-->
<complexType name="chkDataType">
<sequence>
<element name="cd" type="domain:checkType"
maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="checkType">
<sequence>
<element name="name" type="domain:checkNameType"/>
<element name="reason" type="eppcom:reasonType"
minOccurs="0"/>
</sequence>
</complexType>
<complexType name="checkNameType">
<simpleContent>
<extension base="eppcom:labelType">
<attribute name="avail" type="boolean"
use="required"/>
</extension>
</simpleContent>
</complexType>
<!--
<create> response elements.
-->
<complexType name="creDataType">
<sequence>
<element name="name" type="eppcom:labelType"/>
<element name="crDate" type="dateTime"/>
<element name="exDate" type="dateTime"
minOccurs="0"/>
</sequence>
</complexType>
<!--
<info> response elements.
-->
<complexType name="infDataType">
<sequence>
<element name="name" type="eppcom:labelType"/>
<element name="roid" type="eppcom:roidType"/>
<element name="status" type="domain:statusType"
minOccurs="0" maxOccurs="11"/>
<element name="registrant" type="eppcom:clIDType"
minOccurs="0"/>
<element name="contact" type="domain:contactType"
minOccurs="0" maxOccurs="unbounded"/>
<element name="ns" type="domain:nsType"
minOccurs="0"/>
<element name="host" type="eppcom:labelType"
minOccurs="0" maxOccurs="unbounded"/>
<element name="clID" type="eppcom:clIDType"/>
<element name="crID" type="eppcom:clIDType"
minOccurs="0"/>
<element name="crDate" type="dateTime"
minOccurs="0"/>
<element name="upID" type="eppcom:clIDType"
minOccurs="0"/>
<element name="upDate" type="dateTime"
minOccurs="0"/>
<element name="exDate" type="dateTime"
minOccurs="0"/>
<element name="trDate" type="dateTime"
minOccurs="0"/>
<element name="authInfo" type="domain:authInfoType"
minOccurs="0"/>
</sequence>
</complexType>
<!--
Status is a combination of attributes and an optional
human-readable message that may be expressed in languages other
than English.
-->
<complexType name="statusType">
<simpleContent>
<extension base="normalizedString">
<attribute name="s" type="domain:statusValueType"
use="required"/>
<attribute name="lang" type="language"
default="en"/>
</extension>
</simpleContent>
</complexType>
<simpleType name="statusValueType">
<restriction base="token">
<enumeration value="clientDeleteProhibited"/>
<enumeration value="clientHold"/>
<enumeration value="clientRenewProhibited"/>
<enumeration value="clientTransferProhibited"/>
<enumeration value="clientUpdateProhibited"/>
<enumeration value="inactive"/>
<enumeration value="ok"/>
<enumeration value="pendingCreate"/>
<enumeration value="pendingDelete"/>
<enumeration value="pendingRenew"/>
<enumeration value="pendingTransfer"/>
<enumeration value="pendingUpdate"/>
<enumeration value="serverDeleteProhibited"/>
<enumeration value="serverHold"/>
<enumeration value="serverRenewProhibited"/>
<enumeration value="serverTransferProhibited"/>
<enumeration value="serverUpdateProhibited"/>
</restriction>
</simpleType>
<!--
Pending action notification response elements.
-->
<complexType name="panDataType">
<sequence>
<element name="name" type="domain:paNameType"/>
<element name="paTRID" type="epp:trIDType"/>
<element name="paDate" type="dateTime"/>
</sequence>
</complexType>
<complexType name="paNameType">
<simpleContent>
<extension base="eppcom:labelType">
<attribute name="paResult" type="boolean"
use="required"/>
</extension>
</simpleContent>
</complexType>
<!--
<renew> response elements.
-->
<complexType name="renDataType">
<sequence>
<element name="name" type="eppcom:labelType"/>
<element name="exDate" type="dateTime"
minOccurs="0"/>
</sequence>
</complexType>
<!--
<transfer> response elements.
-->
<complexType name="trnDataType">
<sequence>
<element name="name" type="eppcom:labelType"/>
<element name="trStatus" type="eppcom:trStatusType"/>
<element name="reID" type="eppcom:clIDType"/>
<element name="reDate" type="dateTime"/>
<element name="acID" type="eppcom:clIDType"/>
<element name="acDate" type="dateTime"/>
<element name="exDate" type="dateTime"
minOccurs="0"/>
</sequence>
</complexType>
<!--
End of schema.
-->
</schema>

74
doc/schemas/eis-1.0.xsd Normal file
View file

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<schema
targetNamespace="urn:ee:eis:xml:epp:eis-1.0"
xmlns:eis="urn:ee:eis:xml:epp:eis-1.0"
xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<annotation>
<documentation>
EIS Extensible Provisioning Protocol v1.0
extension schema.
</documentation>
</annotation>
<!--
Child elements found in EPP commands.
-->
<element name="extdata" type="eis:legalDocAndIdentType"/>
<!--
Child elements supporting either the
dsData or the keyData interface.
-->
<complexType name="legalDocAndIdentType">
<sequence>
<element name="legalDocument" type="eis:legalDocType"
minOccurs="0" maxOccurs="1"/>
<!-- <element name="ident" type="eis:identType"
minOccurs="0" maxOccurs="1"/> -->
</sequence>
</complexType>
<!--
Child elements of extdata
-->
<complexType name="legalDocType">
<simpleContent>
<extension base="base64Binary">
<attribute name="type" type="eis:legalDocEnumType" use="required"/>
</extension>
</simpleContent>
</complexType>
<simpleType name="legalDocEnumType">
<restriction base="token">
<enumeration value="pdf"/>
<enumeration value="bdoc"/>
<enumeration value="ddoc"/>
<enumeration value="zip"/>
<enumeration value="rar"/>
<enumeration value="gz"/>
<enumeration value="tar"/>
<enumeration value="7z"/>
</restriction>
</simpleType>
<!-- <complexType name="identType">
<simpleContent>
<extension base="normalizedString">
<attribute name="type" type="eis:identEnumType" use="required"/>
</extension>
</simpleContent>
</complexType>
<simpleType name="identEnumType">
<restriction base="token">
<enumeration value="pic"/>
<enumeration value="priv"/>
<enumeration value="birthday"/>
<enumeration value="passport"/>
</restriction>
</simpleType> -->
</schema>

443
doc/schemas/epp-1.0.xsd Normal file
View file

@ -0,0 +1,443 @@
<?xml version="1.0" encoding="UTF-8"?>
<schema targetNamespace="urn:ietf:params:xml:ns:epp-1.0"
xmlns:epp="urn:ietf:params:xml:ns:epp-1.0"
xmlns:eppcom="urn:ietf:params:xml:ns:eppcom-1.0"
xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<!--
Import common element types.
-->
<import namespace="urn:ietf:params:xml:ns:eppcom-1.0" schemaLocation="doc/schemas/eppcom-1.0.xsd" />
<annotation>
<documentation>
Extensible Provisioning Protocol v1.0 schema.
</documentation>
</annotation>
<!--
Every EPP XML instance must begin with this element.
-->
<element name="epp" type="epp:eppType"/>
<!--
An EPP XML instance must contain a greeting, hello, command,
response, or extension.
-->
<complexType name="eppType">
<choice>
<element name="greeting" type="epp:greetingType"/>
<element name="hello"/>
<element name="command" type="epp:commandType"/>
<element name="response" type="epp:responseType"/>
<element name="extension" type="epp:extAnyType"/>
</choice>
</complexType>
<!--
A greeting is sent by a server in response to a client connection
or <hello>.
-->
<complexType name="greetingType">
<sequence>
<element name="svID" type="epp:sIDType"/>
<element name="svDate" type="dateTime"/>
<element name="svcMenu" type="epp:svcMenuType"/>
<element name="dcp" type="epp:dcpType"/>
</sequence>
</complexType>
<!--
Server IDs are strings with minimum and maximum length restrictions.
-->
<simpleType name="sIDType">
<restriction base="normalizedString">
<minLength value="3"/>
<maxLength value="64"/>
</restriction>
</simpleType>
<!--
A server greeting identifies available object services.
-->
<complexType name="svcMenuType">
<sequence>
<element name="version" type="epp:versionType"
maxOccurs="unbounded"/>
<element name="lang" type="language"
maxOccurs="unbounded"/>
<element name="objURI" type="anyURI"
maxOccurs="unbounded"/>
<element name="svcExtension" type="epp:extURIType"
minOccurs="0"/>
</sequence>
</complexType>
<!--
Data Collection Policy types.
-->
<complexType name="dcpType">
<sequence>
<element name="access" type="epp:dcpAccessType"/>
<element name="statement" type="epp:dcpStatementType"
maxOccurs="unbounded"/>
<element name="expiry" type="epp:dcpExpiryType"
minOccurs="0"/>
</sequence>
</complexType>
<complexType name="dcpAccessType">
<choice>
<element name="all"/>
<element name="none"/>
<element name="null"/>
<element name="other"/>
<element name="personal"/>
<element name="personalAndOther"/>
</choice>
</complexType>
<complexType name="dcpStatementType">
<sequence>
<element name="purpose" type="epp:dcpPurposeType"/>
<element name="recipient" type="epp:dcpRecipientType"/>
<element name="retention" type="epp:dcpRetentionType"/>
</sequence>
</complexType>
<complexType name="dcpPurposeType">
<sequence>
<element name="admin"
minOccurs="0"/>
<element name="contact"
minOccurs="0"/>
<element name="other"
minOccurs="0"/>
<element name="prov"
minOccurs="0"/>
</sequence>
</complexType>
<complexType name="dcpRecipientType">
<sequence>
<element name="other"
minOccurs="0"/>
<element name="ours" type="epp:dcpOursType"
minOccurs="0" maxOccurs="unbounded"/>
<element name="public"
minOccurs="0"/>
<element name="same"
minOccurs="0"/>
<element name="unrelated"
minOccurs="0"/>
</sequence>
</complexType>
<complexType name="dcpOursType">
<sequence>
<element name="recDesc" type="epp:dcpRecDescType"
minOccurs="0"/>
</sequence>
</complexType>
<simpleType name="dcpRecDescType">
<restriction base="token">
<minLength value="1"/>
<maxLength value="255"/>
</restriction>
</simpleType>
<complexType name="dcpRetentionType">
<choice>
<element name="business"/>
<element name="indefinite"/>
<element name="legal"/>
<element name="none"/>
<element name="stated"/>
</choice>
</complexType>
<complexType name="dcpExpiryType">
<choice>
<element name="absolute" type="dateTime"/>
<element name="relative" type="duration"/>
</choice>
</complexType>
<!--
Extension framework types.
-->
<complexType name="extAnyType">
<sequence>
<any namespace="##other"
maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="extURIType">
<sequence>
<element name="extURI" type="anyURI"
maxOccurs="unbounded"/>
</sequence>
</complexType>
<!--
An EPP version number is a dotted pair of decimal numbers.
-->
<simpleType name="versionType">
<restriction base="token">
<pattern value="[1-9]+\.[0-9]+"/>
<enumeration value="1.0"/>
</restriction>
</simpleType>
<!--
Command types.
-->
<complexType name="commandType">
<sequence>
<choice>
<element name="check" type="epp:readWriteType"/>
<element name="create" type="epp:readWriteType"/>
<element name="delete" type="epp:readWriteType"/>
<element name="info" type="epp:readWriteType"/>
<element name="login" type="epp:loginType"/>
<element name="logout"/>
<element name="poll" type="epp:pollType"/>
<element name="renew" type="epp:readWriteType"/>
<element name="transfer" type="epp:transferType"/>
<element name="update" type="epp:readWriteType"/>
</choice>
<element name="extension" type="epp:extAnyType"
minOccurs="0"/>
<element name="clTRID" type="epp:trIDStringType"
minOccurs="0"/>
</sequence>
</complexType>
<!--
The <login> command.
-->
<complexType name="loginType">
<sequence>
<element name="clID" type="eppcom:clIDType"/>
<element name="pw" type="epp:pwType"/>
<element name="newPW" type="epp:pwType"
minOccurs="0"/>
<element name="options" type="epp:credsOptionsType"/>
<element name="svcs" type="epp:loginSvcType"/>
</sequence>
</complexType>
<complexType name="credsOptionsType">
<sequence>
<element name="version" type="epp:versionType"/>
<element name="lang" type="language"/>
</sequence>
</complexType>
<simpleType name="pwType">
<restriction base="token">
<minLength value="6"/>
<maxLength value="16"/>
</restriction>
</simpleType>
<complexType name="loginSvcType">
<sequence>
<element name="objURI" type="anyURI"
maxOccurs="unbounded"/>
<element name="svcExtension" type="epp:extURIType"
minOccurs="0"/>
</sequence>
</complexType>
<!--
The <poll> command.
-->
<complexType name="pollType">
<attribute name="op" type="epp:pollOpType"
use="required"/>
<attribute name="msgID" type="token"/>
</complexType>
<simpleType name="pollOpType">
<restriction base="token">
<enumeration value="ack"/>
<enumeration value="req"/>
</restriction>
</simpleType>
<!--
The <transfer> command. This is object-specific, and uses attributes
to identify the requested operation.
-->
<complexType name="transferType">
<sequence>
<any namespace="##other"/>
</sequence>
<attribute name="op" type="epp:transferOpType"
use="required"/>
</complexType>
<simpleType name="transferOpType">
<restriction base="token">
<enumeration value="approve"/>
<enumeration value="cancel"/>
<enumeration value="query"/>
<enumeration value="reject"/>
<enumeration value="request"/>
</restriction>
</simpleType>
<!--
All other object-centric commands. EPP doesn't specify the syntax or
semantics of object-centric command elements. The elements MUST be
described in detail in another schema specific to the object.
-->
<complexType name="readWriteType">
<sequence>
<any namespace="##other"/>
</sequence>
</complexType>
<complexType name="trIDType">
<sequence>
<element name="clTRID" type="epp:trIDStringType"
minOccurs="0"/>
<element name="svTRID" type="epp:trIDStringType"/>
</sequence>
</complexType>
<simpleType name="trIDStringType">
<restriction base="token">
<minLength value="3"/>
<maxLength value="64"/>
</restriction>
</simpleType>
<!--
Response types.
-->
<complexType name="responseType">
<sequence>
<element name="result" type="epp:resultType"
maxOccurs="unbounded"/>
<element name="msgQ" type="epp:msgQType"
minOccurs="0"/>
<element name="resData" type="epp:extAnyType"
minOccurs="0"/>
<element name="extension" type="epp:extAnyType"
minOccurs="0"/>
<element name="trID" type="epp:trIDType"/>
</sequence>
</complexType>
<complexType name="resultType">
<sequence>
<element name="msg" type="epp:msgType"/>
<choice minOccurs="0" maxOccurs="unbounded">
<element name="value" type="epp:errValueType"/>
<element name="extValue" type="epp:extErrValueType"/>
</choice>
</sequence>
<attribute name="code" type="epp:resultCodeType"
use="required"/>
</complexType>
<complexType name="errValueType" mixed="true">
<sequence>
<any namespace="##any" processContents="skip"/>
</sequence>
<anyAttribute namespace="##any" processContents="skip"/>
</complexType>
<complexType name="extErrValueType">
<sequence>
<element name="value" type="epp:errValueType"/>
<element name="reason" type="epp:msgType"/>
</sequence>
</complexType>
<complexType name="msgQType">
<sequence>
<element name="qDate" type="dateTime"
minOccurs="0"/>
<element name="msg" type="epp:mixedMsgType"
minOccurs="0"/>
</sequence>
<attribute name="count" type="unsignedLong"
use="required"/>
<attribute name="id" type="eppcom:minTokenType"
use="required"/>
</complexType>
<complexType name="mixedMsgType" mixed="true">
<sequence>
<any processContents="skip"
minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<attribute name="lang" type="language"
default="en"/>
</complexType>
<!--
Human-readable text may be expressed in languages other than English.
-->
<complexType name="msgType">
<simpleContent>
<extension base="normalizedString">
<attribute name="lang" type="language"
default="en"/>
</extension>
</simpleContent>
</complexType>
<!--
EPP result codes.
-->
<simpleType name="resultCodeType">
<restriction base="unsignedShort">
<enumeration value="1000"/>
<enumeration value="1001"/>
<enumeration value="1300"/>
<enumeration value="1301"/>
<enumeration value="1500"/>
<enumeration value="2000"/>
<enumeration value="2001"/>
<enumeration value="2002"/>
<enumeration value="2003"/>
<enumeration value="2004"/>
<enumeration value="2005"/>
<enumeration value="2100"/>
<enumeration value="2101"/>
<enumeration value="2102"/>
<enumeration value="2103"/>
<enumeration value="2104"/>
<enumeration value="2105"/>
<enumeration value="2106"/>
<enumeration value="2200"/>
<enumeration value="2201"/>
<enumeration value="2202"/>
<enumeration value="2300"/>
<enumeration value="2301"/>
<enumeration value="2302"/>
<enumeration value="2303"/>
<enumeration value="2304"/>
<enumeration value="2305"/>
<enumeration value="2306"/>
<enumeration value="2307"/>
<enumeration value="2308"/>
<enumeration value="2400"/>
<enumeration value="2500"/>
<enumeration value="2501"/>
<enumeration value="2502"/>
</restriction>
</simpleType>
<!--
End of schema.
-->
</schema>

104
doc/schemas/eppcom-1.0.xsd Normal file
View file

@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8"?>
<schema targetNamespace="urn:ietf:params:xml:ns:eppcom-1.0"
xmlns:eppcom="urn:ietf:params:xml:ns:eppcom-1.0"
xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<annotation>
<documentation>
Extensible Provisioning Protocol v1.0
shared structures schema.
</documentation>
</annotation>
<!--
Object authorization information types.
-->
<complexType name="pwAuthInfoType">
<simpleContent>
<extension base="normalizedString">
<attribute name="roid" type="eppcom:roidType"/>
</extension>
</simpleContent>
</complexType>
<complexType name="extAuthInfoType">
<sequence>
<any namespace="##other"/>
</sequence>
</complexType>
<!--
<check> response types.
-->
<complexType name="reasonType">
<simpleContent>
<extension base="eppcom:reasonBaseType">
<attribute name="lang" type="language"/>
</extension>
</simpleContent>
</complexType>
<simpleType name="reasonBaseType">
<restriction base="token">
<minLength value="1"/>
<maxLength value="32"/>
</restriction>
</simpleType>
<!--
Abstract client and object identifier type.
-->
<simpleType name="clIDType">
<restriction base="token">
<minLength value="3"/>
</restriction>
</simpleType>
<!--
DNS label type.
-->
<simpleType name="labelType">
<restriction base="token">
<minLength value="1"/>
<maxLength value="255"/>
</restriction>
</simpleType>
<!--
Non-empty token type.
-->
<simpleType name="minTokenType">
<restriction base="token">
<minLength value="1"/>
</restriction>
</simpleType>
<!--
Repository Object IDentifier type.
-->
<simpleType name="roidType">
<restriction base="token">
<pattern value="(\w|_){1,80}-\w{1,8}"/>
</restriction>
</simpleType>
<!--
Transfer status identifiers.
-->
<simpleType name="trStatusType">
<restriction base="token">
<enumeration value="clientApproved"/>
<enumeration value="clientCancelled"/>
<enumeration value="clientRejected"/>
<enumeration value="pending"/>
<enumeration value="serverApproved"/>
<enumeration value="serverCancelled"/>
</restriction>
</simpleType>
<!--
End of schema.
-->
</schema>

244
doc/schemas/host-1.0.xsd Normal file
View file

@ -0,0 +1,244 @@
<?xml version="1.0" encoding="UTF-8"?>
<schema targetNamespace="urn:ietf:params:xml:ns:host-1.0"
xmlns:host="urn:ietf:params:xml:ns:host-1.0"
xmlns:epp="urn:ietf:params:xml:ns:epp-1.0"
xmlns:eppcom="urn:ietf:params:xml:ns:eppcom-1.0"
xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<!--
Import common element types.
-->
<import namespace="urn:ietf:params:xml:ns:eppcom-1.0"
schemaLocation="eppcom-1.0.xsd"/>
<import namespace="urn:ietf:params:xml:ns:epp-1.0"
schemaLocation="epp-1.0.xsd"/>
<annotation>
<documentation>
Extensible Provisioning Protocol v1.0
host provisioning schema.
</documentation>
</annotation>
<!--
Child elements found in EPP commands.
-->
<element name="check" type="host:mNameType"/>
<element name="create" type="host:createType"/>
<element name="delete" type="host:sNameType"/>
<element name="info" type="host:sNameType"/>
<element name="update" type="host:updateType"/>
<!--
Child elements of the <create> command.
-->
<complexType name="createType">
<sequence>
<element name="name" type="eppcom:labelType"/>
<element name="addr" type="host:addrType"
minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="addrType">
<simpleContent>
<extension base="host:addrStringType">
<attribute name="ip" type="host:ipType"
default="v4"/>
</extension>
</simpleContent>
</complexType>
<simpleType name="addrStringType">
<restriction base="token">
<minLength value="3"/>
<maxLength value="45"/>
</restriction>
</simpleType>
<simpleType name="ipType">
<restriction base="token">
<enumeration value="v4"/>
<enumeration value="v6"/>
</restriction>
</simpleType>
<!--
Child elements of the <delete> and <info> commands.
-->
<complexType name="sNameType">
<sequence>
<element name="name" type="eppcom:labelType"/>
</sequence>
</complexType>
<!--
Child element of commands that accept multiple names.
-->
<complexType name="mNameType">
<sequence>
<element name="name" type="eppcom:labelType"
maxOccurs="unbounded"/>
</sequence>
</complexType>
<!--
Child elements of the <update> command.
-->
<complexType name="updateType">
<sequence>
<element name="name" type="eppcom:labelType"/>
<element name="add" type="host:addRemType"
minOccurs="0"/>
<element name="rem" type="host:addRemType"
minOccurs="0"/>
<element name="chg" type="host:chgType"
minOccurs="0"/>
</sequence>
</complexType>
<!--
Data elements that can be added or removed.
-->
<complexType name="addRemType">
<sequence>
<element name="addr" type="host:addrType"
minOccurs="0" maxOccurs="unbounded"/>
<element name="status" type="host:statusType"
minOccurs="0" maxOccurs="7"/>
</sequence>
</complexType>
<!--
Data elements that can be changed.
-->
<complexType name="chgType">
<sequence>
<element name="name" type="eppcom:labelType"/>
</sequence>
</complexType>
<!--
Child response elements.
-->
<element name="chkData" type="host:chkDataType"/>
<element name="creData" type="host:creDataType"/>
<element name="infData" type="host:infDataType"/>
<element name="panData" type="host:panDataType"/>
<!--
<check> response elements.
-->
<complexType name="chkDataType">
<sequence>
<element name="cd" type="host:checkType"
maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="checkType">
<sequence>
<element name="name" type="host:checkNameType"/>
<element name="reason" type="eppcom:reasonType"
minOccurs="0"/>
</sequence>
</complexType>
<complexType name="checkNameType">
<simpleContent>
<extension base="eppcom:labelType">
<attribute name="avail" type="boolean"
use="required"/>
</extension>
</simpleContent>
</complexType>
<!--
<create> response elements.
-->
<complexType name="creDataType">
<sequence>
<element name="name" type="eppcom:labelType"/>
<element name="crDate" type="dateTime"/>
</sequence>
</complexType>
<!--
<info> response elements.
-->
<complexType name="infDataType">
<sequence>
<element name="name" type="eppcom:labelType"/>
<element name="roid" type="eppcom:roidType"/>
<element name="status" type="host:statusType"
maxOccurs="7"/>
<element name="addr" type="host:addrType"
minOccurs="0" maxOccurs="unbounded"/>
<element name="clID" type="eppcom:clIDType"/>
<element name="crID" type="eppcom:clIDType"/>
<element name="crDate" type="dateTime"/>
<element name="upID" type="eppcom:clIDType"
minOccurs="0"/>
<element name="upDate" type="dateTime"
minOccurs="0"/>
<element name="trDate" type="dateTime"
minOccurs="0"/>
</sequence>
</complexType>
<!--
Status is a combination of attributes and an optional human-readable
message that may be expressed in languages other than English.
-->
<complexType name="statusType">
<simpleContent>
<extension base="normalizedString">
<attribute name="s" type="host:statusValueType"
use="required"/>
<attribute name="lang" type="language"
default="en"/>
</extension>
</simpleContent>
</complexType>
<simpleType name="statusValueType">
<restriction base="token">
<enumeration value="clientDeleteProhibited"/>
<enumeration value="clientUpdateProhibited"/>
<enumeration value="linked"/>
<enumeration value="ok"/>
<enumeration value="pendingCreate"/>
<enumeration value="pendingDelete"/>
<enumeration value="pendingTransfer"/>
<enumeration value="pendingUpdate"/>
<enumeration value="serverDeleteProhibited"/>
<enumeration value="serverUpdateProhibited"/>
</restriction>
</simpleType>
<!--
Pending action notification response elements.
-->
<complexType name="panDataType">
<sequence>
<element name="name" type="host:paNameType"/>
<element name="paTRID" type="epp:trIDType"/>
<element name="paDate" type="dateTime"/>
</sequence>
</complexType>
<complexType name="paNameType">
<simpleContent>
<extension base="eppcom:labelType">
<attribute name="paResult" type="boolean"
use="required"/>
</extension>
</simpleContent>
</complexType>
<!--
End of schema.
-->
</schema>

130
doc/schemas/secDNS-1.1.xsd Normal file
View file

@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8"?>
<schema
targetNamespace="urn:ietf:params:xml:ns:secDNS-1.1"
xmlns:secDNS="urn:ietf:params:xml:ns:secDNS-1.1"
xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<annotation>
<documentation>
Extensible Provisioning Protocol v1.0
domain name extension schema
for provisioning DNS security (DNSSEC) extensions.
</documentation>
</annotation>
<!--
Child elements found in EPP commands.
-->
<element name="create" type="secDNS:dsOrKeyType"/>
<element name="update" type="secDNS:updateType"/>
<!--
Child elements supporting either the
dsData or the keyData interface.
-->
<complexType name="dsOrKeyType">
<sequence>
<element name="maxSigLife" type="secDNS:maxSigLifeType"
minOccurs="0"/>
<choice>
<element name="dsData" type="secDNS:dsDataType"
maxOccurs="unbounded"/>
<element name="keyData" type="secDNS:keyDataType"
maxOccurs="unbounded"/>
</choice>
</sequence>
</complexType>
<!--
Definition for the maximum signature lifetime (maxSigLife)
-->
<simpleType name="maxSigLifeType">
<restriction base="int">
<minInclusive value="1"/>
</restriction>
</simpleType>
<!--
Child elements of dsData used for dsData interface
-->
<complexType name="dsDataType">
<sequence>
<element name="keyTag" type="unsignedShort"/>
<element name="alg" type="unsignedByte"/>
<element name="digestType" type="unsignedByte"/>
<element name="digest" type="hexBinary"/>
<element name="keyData" type="secDNS:keyDataType"
minOccurs="0"/>
</sequence>
</complexType>
<!--
Child elements of keyData used for keyData interface
and optionally with dsData interface
-->
<complexType name="keyDataType">
<sequence>
<element name="flags" type="unsignedShort"/>
<element name="protocol" type="unsignedByte"/>
<element name="alg" type="unsignedByte"/>
<element name="pubKey" type="secDNS:keyType"/>
</sequence>
</complexType>
<!--
Definition for the public key
-->
<simpleType name="keyType">
<restriction base="base64Binary">
<minLength value="1"/>
</restriction>
</simpleType>
<!--
Child elements of the <update> element.
-->
<complexType name="updateType">
<sequence>
<element name="rem" type="secDNS:remType"
minOccurs="0"/>
<element name="add" type="secDNS:dsOrKeyType"
minOccurs="0"/>
<element name="chg" type="secDNS:chgType"
minOccurs="0"/>
</sequence>
<attribute name="urgent" type="boolean" default="false"/>
</complexType>
<!--
Child elements of the <rem> command.
-->
<complexType name="remType">
<choice>
<element name="all" type="boolean"/>
<element name="dsData" type="secDNS:dsDataType"
maxOccurs="unbounded"/>
<element name="keyData" type="secDNS:keyDataType"
maxOccurs="unbounded"/>
</choice>
</complexType>
<!--
Child elements supporting the <chg> element.
-->
<complexType name="chgType">
<sequence>
<element name="maxSigLife" type="secDNS:maxSigLifeType"
minOccurs="0"/>
</sequence>
</complexType>
<!--
Child response elements.
-->
<element name="infData" type="secDNS:dsOrKeyType"/>
</schema>

View file

@ -939,15 +939,6 @@ describe 'EPP Contact', epp: true do
end end
end end
end end
context 'renew command' do
it 'returns 2101-unimplemented command' do
response = epp_plain_request('contacts/renew.xml')
response[:msg].should == 'Unimplemented command'
response[:result_code].should == '2101'
end
end
end end
def check_multiple_contacts_xml def check_multiple_contacts_xml

View file

@ -2,6 +2,7 @@ require 'rails_helper'
describe 'EPP Domain', epp: true do describe 'EPP Domain', epp: true do
before(:all) do before(:all) do
@xsd = Nokogiri::XML::Schema(File.read('doc/schemas/domain-1.0.xsd'))
@epp_xml = EppXml.new(cl_trid: 'ABC-12345') @epp_xml = EppXml.new(cl_trid: 'ABC-12345')
@registrar1 = Fabricate(:registrar1, code: 'REGDOMAIN1') @registrar1 = Fabricate(:registrar1, code: 'REGDOMAIN1')
@registrar2 = Fabricate(:registrar2, code: 'REGDOMAIN2') @registrar2 = Fabricate(:registrar2, code: 'REGDOMAIN2')
@ -27,7 +28,7 @@ describe 'EPP Domain', epp: true do
{ contact: { value: 'sh1111', attrs: { type: 'tech' } } }, { contact: { value: 'sh1111', attrs: { type: 'tech' } } },
{ contact: { value: 'sh2222', attrs: { type: 'tech' } } } { contact: { value: 'sh2222', attrs: { type: 'tech' } } }
] ]
}), :xml) }))
response[:results][0][:msg].should == 'Contact was not found' response[:results][0][:msg].should == 'Contact was not found'
response[:results][0][:result_code].should == '2303' response[:results][0][:result_code].should == '2303'
@ -56,7 +57,7 @@ describe 'EPP Domain', epp: true do
name: { value: 'test.ee' } name: { value: 'test.ee' }
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:results][0][:result_code].should == '2003' response[:results][0][:result_code].should == '2003'
response[:results][0][:msg].should == response[:results][0][:msg].should ==
'Required parameter missing: create > create > ns [ns]' 'Required parameter missing: create > create > ns [ns]'
@ -79,7 +80,7 @@ describe 'EPP Domain', epp: true do
dn = next_domain_name dn = next_domain_name
response = epp_plain_request(domain_create_xml({ response = epp_plain_request(domain_create_xml({
name: { value: dn } name: { value: dn }
}), :xml) }))
d = Domain.last d = Domain.last
response[:msg].should == 'Command completed successfully' response[:msg].should == 'Command completed successfully'
@ -115,7 +116,7 @@ describe 'EPP Domain', epp: true do
end end
it 'creates a domain with legal document' do it 'creates a domain with legal document' do
response = epp_plain_request(domain_create_xml_with_legal_doc, :xml) response = epp_plain_request(domain_create_xml_with_legal_doc)
response[:msg].should == 'Command completed successfully' response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000' response[:result_code].should == '1000'
@ -143,7 +144,7 @@ describe 'EPP Domain', epp: true do
# ] # ]
# }) # })
# epp_plain_request(xml, :xml) # epp_plain_request(xml)
# d = Domain.last # d = Domain.last
# ds = d.dnskeys.last # ds = d.dnskeys.last
@ -168,7 +169,7 @@ describe 'EPP Domain', epp: true do
] ]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:result_code].should == '2306' response[:result_code].should == '2306'
response[:msg].should == 'IPv4 is missing [ipv4]' response[:msg].should == 'IPv4 is missing [ipv4]'
@ -178,10 +179,10 @@ describe 'EPP Domain', epp: true do
# dn = next_domain_name # dn = next_domain_name
# epp_plain_request(domain_create_xml({ # epp_plain_request(domain_create_xml({
# name: { value: dn } # name: { value: dn }
# }), :xml) # }))
# response = epp_plain_request(domain_create_xml({ # response = epp_plain_request(domain_create_xml({
# name: { value: dn } # name: { value: dn }
# }), :xml) # }))
# response[:msg].should == 'Domain name already exists' # response[:msg].should == 'Domain name already exists'
# response[:result_code].should == '2302' # response[:result_code].should == '2302'
@ -191,24 +192,24 @@ describe 'EPP Domain', epp: true do
it 'does not create reserved domain' do it 'does not create reserved domain' do
xml = domain_create_xml(name: { value: '1162.ee' }) xml = domain_create_xml(name: { value: '1162.ee' })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:result_code].should == '2302' response[:result_code].should == '2302'
response[:msg].should == 'Domain name is reserved or restricted [name_dirty]' response[:msg].should == 'Domain name is reserved or restricted [name_dirty]'
response[:clTRID].should == 'ABC-12345' response[:clTRID].should == 'ABC-12345'
end end
it 'does not create domain without contacts and registrant' do it 'does not create domain without contacts and registrant' do
xml = domain_create_xml(contacts: [], registrant: false) xml = domain_create_xml(_anonymus: [], registrant: false)
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:results][0][:result_code].should == '2003' response[:results][0][:result_code].should == '2003'
response[:results][0][:msg].should == response[:results][0][:msg].should ==
'Required parameter missing: create > create > registrant [registrant]' 'Required parameter missing: create > create > registrant [registrant]'
end end
it 'does not create domain without nameservers' do it 'does not create domain without nameservers' do
xml = domain_create_xml(ns: []) xml = domain_create_xml(ns: nil)
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:results][0][:msg].should == response[:results][0][:msg].should ==
'Required parameter missing: create > create > ns [ns]' 'Required parameter missing: create > create > ns [ns]'
@ -235,7 +236,7 @@ describe 'EPP Domain', epp: true do
ns: nameservers ns: nameservers
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:result_code].should == '2004' response[:result_code].should == '2004'
response[:msg].should == 'Nameservers count must be between 2-11 [nameservers]' response[:msg].should == 'Nameservers count must be between 2-11 [nameservers]'
end end
@ -256,7 +257,7 @@ describe 'EPP Domain', epp: true do
] ]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:msg].should == 'Hostname is invalid [hostname]' response[:msg].should == 'Hostname is invalid [hostname]'
response[:result_code].should == '2005' response[:result_code].should == '2005'
end end
@ -273,13 +274,13 @@ describe 'EPP Domain', epp: true do
] ]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:msg].should == 'Required parameter missing: create > create > ns > hostAttr [host_attr]' response[:msg].should == 'Required parameter missing: create > create > ns > hostAttr [host_attr]'
response[:result_code].should == '2003' response[:result_code].should == '2003'
end end
it 'creates domain with nameservers with ips' do it 'creates domain with nameservers with ips' do
epp_plain_request(domain_create_with_host_attrs, :xml) epp_plain_request(domain_create_with_host_attrs)
Domain.last.nameservers.count.should == 2 Domain.last.nameservers.count.should == 2
ns = Domain.last.nameservers.first ns = Domain.last.nameservers.first
ns.ipv4.should == '192.0.2.2' ns.ipv4.should == '192.0.2.2'
@ -289,7 +290,7 @@ describe 'EPP Domain', epp: true do
it 'returns error when nameserver has invalid ips' do it 'returns error when nameserver has invalid ips' do
domain_count = Domain.count domain_count = Domain.count
nameserver_count = Nameserver.count nameserver_count = Nameserver.count
response = epp_plain_request(domain_create_with_invalid_ns_ip_xml, :xml) response = epp_plain_request(domain_create_with_invalid_ns_ip_xml)
response[:results][0][:result_code].should == '2005' response[:results][0][:result_code].should == '2005'
response[:results][0][:msg].should == 'IPv4 is invalid [ipv4]' response[:results][0][:msg].should == 'IPv4 is invalid [ipv4]'
response[:results][0][:value].should == '192.0.2.2.invalid' response[:results][0][:value].should == '192.0.2.2.invalid'
@ -304,7 +305,7 @@ describe 'EPP Domain', epp: true do
it 'creates a domain with period in days' do it 'creates a domain with period in days' do
xml = domain_create_xml(period_value: 365, period_unit: 'd') xml = domain_create_xml(period_value: 365, period_unit: 'd')
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:msg].should == 'Command completed successfully' response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000' response[:result_code].should == '1000'
Domain.first.valid_to.should == 1.year.since.to_date Domain.first.valid_to.should == 1.year.since.to_date
@ -315,7 +316,7 @@ describe 'EPP Domain', epp: true do
period: { value: '367', attrs: { unit: 'd' } } period: { value: '367', attrs: { unit: 'd' } }
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:results][0][:result_code].should == '2004' response[:results][0][:result_code].should == '2004'
response[:results][0][:msg].should == 'Period must add up to 1, 2 or 3 years [period]' response[:results][0][:msg].should == 'Period must add up to 1, 2 or 3 years [period]'
response[:results][0][:value].should == '367' response[:results][0][:value].should == '367'
@ -350,7 +351,7 @@ describe 'EPP Domain', epp: true do
] ]
}) })
epp_plain_request(xml, :xml) epp_plain_request(xml)
d = Domain.last d = Domain.last
d.dnskeys.count.should == 3 d.dnskeys.count.should == 3
@ -406,7 +407,7 @@ describe 'EPP Domain', epp: true do
] ]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml, validate_input: false)
response[:results][0][:msg].should == response[:results][0][:msg].should ==
'Valid algorithms are: 3, 5, 6, 7, 8, 252, 253, 254, 255 [alg]' 'Valid algorithms are: 3, 5, 6, 7, 8, 252, 253, 254, 255 [alg]'
@ -450,7 +451,7 @@ describe 'EPP Domain', epp: true do
}] }]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:result_code].should == '2302' response[:result_code].should == '2302'
response[:msg].should == 'Public key already exists [public_key]' response[:msg].should == 'Public key already exists [public_key]'
@ -479,7 +480,7 @@ describe 'EPP Domain', epp: true do
}] }]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:result_code].should == '2004' response[:result_code].should == '2004'
response[:msg].should == 'DNS keys count must be between 0-1 [dnskeys]' response[:msg].should == 'DNS keys count must be between 0-1 [dnskeys]'
@ -499,7 +500,7 @@ describe 'EPP Domain', epp: true do
}] }]
}) })
epp_plain_request(xml, :xml) epp_plain_request(xml)
d = Domain.last d = Domain.last
ds = d.dnskeys.first ds = d.dnskeys.first
@ -531,7 +532,7 @@ describe 'EPP Domain', epp: true do
}] }]
}) })
epp_plain_request(xml, :xml) epp_plain_request(xml)
d = Domain.last d = Domain.last
ds = d.dnskeys.first ds = d.dnskeys.first
@ -565,7 +566,7 @@ describe 'EPP Domain', epp: true do
# }] # }]
# }) # })
# response = epp_plain_request(xml, :xml) # response = epp_plain_request(xml)
# response[:result_code].should == '2306' # response[:result_code].should == '2306'
# response[:msg].should == 'dsData object with key data is not allowed' # response[:msg].should == 'dsData object with key data is not allowed'
@ -592,7 +593,7 @@ describe 'EPP Domain', epp: true do
}] }]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:result_code].should == '2306' response[:result_code].should == '2306'
response[:msg].should == 'dsData object is not allowed' response[:msg].should == 'dsData object is not allowed'
@ -612,7 +613,7 @@ describe 'EPP Domain', epp: true do
}] }]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:result_code].should == '2306' response[:result_code].should == '2306'
response[:msg].should == 'keyData object is not allowed' response[:msg].should == 'keyData object is not allowed'
@ -640,7 +641,7 @@ describe 'EPP Domain', epp: true do
}] }]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml, validate_input: false)
response[:msg].should == 'Mutually exclusive parameters: extension > create > keyData, '\ response[:msg].should == 'Mutually exclusive parameters: extension > create > keyData, '\
'extension > create > dsData' 'extension > create > dsData'
response[:result_code].should == '2306' response[:result_code].should == '2306'
@ -656,7 +657,7 @@ describe 'EPP Domain', epp: true do
] ]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:msg].should == 'Command completed successfully' response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000' response[:result_code].should == '1000'
response[:clTRID].should == 'ABC-12345' response[:clTRID].should == 'ABC-12345'
@ -678,7 +679,7 @@ describe 'EPP Domain', epp: true do
] ]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:msg].should == 'Admin contacts count must be between 1-10 [admin_domain_contacts]' response[:msg].should == 'Admin contacts count must be between 1-10 [admin_domain_contacts]'
response[:result_code].should == '2004' response[:result_code].should == '2004'
response[:clTRID].should == 'ABC-12345' response[:clTRID].should == 'ABC-12345'
@ -695,7 +696,7 @@ describe 'EPP Domain', epp: true do
] ]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:msg].should == 'Admin contact can be private person only' response[:msg].should == 'Admin contact can be private person only'
response[:result_code].should == '2306' response[:result_code].should == '2306'
end end
@ -716,14 +717,14 @@ describe 'EPP Domain', epp: true do
}, 'query', { }, 'query', {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
}) })
response = login_as :registrar2 do response = login_as :registrar2 do
epp_plain_request(xml, :xml) epp_plain_request(xml)
end end
domain.reload domain.reload
@ -740,7 +741,7 @@ describe 'EPP Domain', epp: true do
domain.registrar.should == @registrar2 domain.registrar.should == @registrar2
response = epp_plain_request(@epp_xml.session.poll, :xml) response = epp_plain_request(@epp_xml.session.poll)
response[:msg].should == 'Command completed successfully; ack to dequeue' response[:msg].should == 'Command completed successfully; ack to dequeue'
msg_q = response[:parsed].css('msgQ') msg_q = response[:parsed].css('msgQ')
@ -760,13 +761,13 @@ describe 'EPP Domain', epp: true do
}, 'query', { }, 'query', {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
}) # request with new password }) # request with new password
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
trn_data = response[:parsed].css('trnData') trn_data = response[:parsed].css('trnData')
domain.reload domain.reload
@ -785,7 +786,7 @@ describe 'EPP Domain', epp: true do
domain.registrar.should == @registrar2 domain.registrar.should == @registrar2
# should return same data if pending already # should return same data if pending already
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
trn_data = response[:parsed].css('trnData') trn_data = response[:parsed].css('trnData')
domain.domain_transfers.count.should == 2 domain.domain_transfers.count.should == 2
@ -802,7 +803,7 @@ describe 'EPP Domain', epp: true do
# should show up in other registrar's poll # should show up in other registrar's poll
response = login_as :registrar2 do response = login_as :registrar2 do
epp_plain_request(@epp_xml.session.poll, :xml) epp_plain_request(@epp_xml.session.poll)
end end
response[:msg].should == 'Command completed successfully; ack to dequeue' response[:msg].should == 'Command completed successfully; ack to dequeue'
@ -817,7 +818,7 @@ describe 'EPP Domain', epp: true do
}) })
response = login_as :registrar2 do response = login_as :registrar2 do
epp_plain_request(xml, :xml) epp_plain_request(xml)
end end
response[:msg].should == 'Command completed successfully' response[:msg].should == 'Command completed successfully'
@ -838,14 +839,14 @@ describe 'EPP Domain', epp: true do
}, 'query', { }, 'query', {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
}) })
login_as :registrar2 do login_as :registrar2 do
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:result_code].should == '1000' response[:result_code].should == '1000'
domain.legal_documents.count.should == 1 domain.legal_documents.count.should == 1
@ -861,7 +862,7 @@ describe 'EPP Domain', epp: true do
end end
response = login_as :registrar2 do response = login_as :registrar2 do
epp_plain_request(xml, :xml) epp_plain_request(xml)
end end
response[:result_code].should == '1000' response[:result_code].should == '1000'
@ -878,7 +879,7 @@ describe 'EPP Domain', epp: true do
}) })
login_as :registrar2 do login_as :registrar2 do
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:msg].should == 'Command completed successfully' response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000' response[:result_code].should == '1000'
end end
@ -897,7 +898,7 @@ describe 'EPP Domain', epp: true do
}) })
login_as :registrar2 do login_as :registrar2 do
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:msg].should == 'Command completed successfully' response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000' response[:result_code].should == '1000'
end end
@ -930,7 +931,7 @@ describe 'EPP Domain', epp: true do
}) })
login_as :registrar2 do login_as :registrar2 do
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:msg].should == 'Command completed successfully' response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000' response[:result_code].should == '1000'
end end
@ -965,7 +966,7 @@ describe 'EPP Domain', epp: true do
}) })
login_as :registrar2 do login_as :registrar2 do
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:msg].should == 'Command completed successfully' response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000' response[:result_code].should == '1000'
end end
@ -1003,7 +1004,7 @@ describe 'EPP Domain', epp: true do
}) })
login_as :registrar2 do login_as :registrar2 do
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:msg].should == 'Command completed successfully' response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000' response[:result_code].should == '1000'
end end
@ -1057,7 +1058,7 @@ describe 'EPP Domain', epp: true do
}) })
login_as :registrar2 do login_as :registrar2 do
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:msg].should == 'Command completed successfully' response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000' response[:result_code].should == '1000'
end end
@ -1110,7 +1111,7 @@ describe 'EPP Domain', epp: true do
}) })
login_as :registrar2 do login_as :registrar2 do
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:msg].should == 'Command completed successfully' response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000' response[:result_code].should == '1000'
end end
@ -1143,7 +1144,7 @@ describe 'EPP Domain', epp: true do
}) })
login_as :registrar2 do login_as :registrar2 do
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:msg].should == 'Command completed successfully' response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000' response[:result_code].should == '1000'
end end
@ -1163,7 +1164,7 @@ describe 'EPP Domain', epp: true do
}) })
login_as :registrar2 do login_as :registrar2 do
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:msg].should == 'Authorization error' response[:msg].should == 'Authorization error'
response[:result_code].should == '2201' response[:result_code].should == '2201'
end end
@ -1183,13 +1184,13 @@ describe 'EPP Domain', epp: true do
}, 'approve', { }, 'approve', {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
domain.reload domain.reload
dtl = domain.domain_transfers.last dtl = domain.domain_transfers.last
@ -1219,21 +1220,21 @@ describe 'EPP Domain', epp: true do
}, 'reject', { }, 'reject', {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
}) })
response = login_as :registrar2 do response = login_as :registrar2 do
epp_plain_request(xml, :xml) epp_plain_request(xml)
end end
response[:msg].should == 'Transfer can be rejected only by current registrar' response[:msg].should == 'Transfer can be rejected only by current registrar'
response[:result_code].should == '2304' response[:result_code].should == '2304'
domain.legal_documents.count.should == 0 domain.legal_documents.count.should == 0
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:result_code].should == '1000' response[:result_code].should == '1000'
domain.pending_transfer.should be_nil domain.pending_transfer.should be_nil
domain.legal_documents.count.should == 1 domain.legal_documents.count.should == 1
@ -1253,14 +1254,14 @@ describe 'EPP Domain', epp: true do
}, 'approve', { }, 'approve', {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
}) })
response = login_as :registrar2 do response = login_as :registrar2 do
epp_plain_request(xml, :xml) epp_plain_request(xml)
end end
response[:result_code].should == '2304' response[:result_code].should == '2304'
@ -1274,13 +1275,13 @@ describe 'EPP Domain', epp: true do
}, 'query', { }, 'query', {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:result_code].should == '2201' response[:result_code].should == '2201'
response[:msg].should == 'Authorization error' response[:msg].should == 'Authorization error'
end end
@ -1293,20 +1294,20 @@ describe 'EPP Domain', epp: true do
}, 'query', { }, 'query', {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:result_code].should == '2002' response[:result_code].should == '2002'
response[:msg].should == 'Domain already belongs to the querying registrar' response[:msg].should == 'Domain already belongs to the querying registrar'
end end
it 'returns an error for incorrect op attribute' do it 'returns an error for incorrect op attribute' do
response = epp_plain_request(domain_transfer_xml({}, 'bla'), :xml) response = epp_plain_request(domain_transfer_xml({}, 'bla'), validate_input: false)
response[:result_code].should == '2306' response[:result_code].should == '2306'
response[:msg].should == 'Attribute is invalid: op' response[:msg].should == 'Attribute is invalid: op'
end end
@ -1319,15 +1320,15 @@ describe 'EPP Domain', epp: true do
}, 'query', { }, 'query', {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
}) })
login_as :registrar2 do login_as :registrar2 do
epp_plain_request(xml, :xml) # transfer domain epp_plain_request(xml) # transfer domain
response = epp_plain_request(xml, :xml) # attempt second transfer response = epp_plain_request(xml) # attempt second transfer
response[:result_code].should == '2201' response[:result_code].should == '2201'
response[:msg].should == 'Authorization error' response[:msg].should == 'Authorization error'
end end
@ -1341,13 +1342,13 @@ describe 'EPP Domain', epp: true do
}, 'approve', { }, 'approve', {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:msg].should == 'Pending transfer was not found' response[:msg].should == 'Pending transfer was not found'
response[:result_code].should == '2303' response[:result_code].should == '2303'
end end
@ -1366,11 +1367,11 @@ describe 'EPP Domain', epp: true do
response = epp_plain_request(domain_update_xml(xml_params, {}, { response = epp_plain_request(domain_update_xml(xml_params, {}, {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
}), :xml) }))
response[:results][0][:msg].should == 'Command completed successfully' response[:results][0][:msg].should == 'Command completed successfully'
response[:results][0][:result_code].should == '1000' response[:results][0][:result_code].should == '1000'
@ -1395,11 +1396,11 @@ describe 'EPP Domain', epp: true do
response = epp_plain_request(domain_update_xml(xml_params, {}, { response = epp_plain_request(domain_update_xml(xml_params, {}, {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
}), :xml) }))
response[:results][0][:msg].should == 'Command completed successfully; action pending' response[:results][0][:msg].should == 'Command completed successfully; action pending'
response[:results][0][:result_code].should == '1001' response[:results][0][:result_code].should == '1001'
@ -1503,11 +1504,11 @@ describe 'EPP Domain', epp: true do
response = epp_plain_request(domain_update_xml(xml_params, {}, { response = epp_plain_request(domain_update_xml(xml_params, {}, {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
}), :xml) }))
response[:results][0][:msg].should == 'Object status prohibits operation' response[:results][0][:msg].should == 'Object status prohibits operation'
response[:results][0][:result_code].should == '2304' response[:results][0][:result_code].should == '2304'
@ -1563,13 +1564,13 @@ describe 'EPP Domain', epp: true do
] ]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:results][0][:result_code].should == '2303' response[:results][0][:result_code].should == '2303'
response[:results][0][:msg].should == 'Contact was not found' response[:results][0][:msg].should == 'Contact was not found'
Fabricate(:contact, code: 'FIXED:MAK21') Fabricate(:contact, code: 'FIXED:MAK21')
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:results][0][:result_code].should == '1000' response[:results][0][:result_code].should == '1000'
d = Domain.last d = Domain.last
@ -1587,7 +1588,7 @@ describe 'EPP Domain', epp: true do
d.domain_statuses.last.value.should == 'clientUpdateProhibited' d.domain_statuses.last.value.should == 'clientUpdateProhibited'
d.dnskeys.count.should == 2 d.dnskeys.count.should == 2
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:results][0][:result_code].should == '2302' response[:results][0][:result_code].should == '2302'
response[:results][0][:msg].should == 'Nameserver already exists on this domain [hostname]' response[:results][0][:msg].should == 'Nameserver already exists on this domain [hostname]'
@ -1647,9 +1648,6 @@ describe 'EPP Domain', epp: true do
it 'updates domain with registrant change what triggers action pending' do it 'updates domain with registrant change what triggers action pending' do
xml = domain_update_xml({ xml = domain_update_xml({
name: { value: domain.name }, name: { value: domain.name },
chg: [
registrant: { value: 'FIXED:CITIZEN_1234' }
],
add: [ add: [
{ {
ns: [ ns: [
@ -1670,6 +1668,9 @@ describe 'EPP Domain', epp: true do
{ status: { value: 'Payment overdue.', attrs: { s: 'clientHold', lang: 'en' } } }, { status: { value: 'Payment overdue.', attrs: { s: 'clientHold', lang: 'en' } } },
{ status: { value: '', attrs: { s: 'clientUpdateProhibited' } } } { status: { value: '', attrs: { s: 'clientUpdateProhibited' } } }
] ]
],
chg: [
registrant: { value: 'FIXED:CITIZEN_1234' }
] ]
}, { }, {
add: [ add: [
@ -1693,19 +1694,19 @@ describe 'EPP Domain', epp: true do
{ {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:results][0][:msg].should == 'Contact was not found' response[:results][0][:msg].should == 'Contact was not found'
response[:results][0][:result_code].should == '2303' response[:results][0][:result_code].should == '2303'
Fabricate(:contact, code: 'FIXED:PENDINGMAK21') Fabricate(:contact, code: 'FIXED:PENDINGMAK21')
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:results][0][:msg].should == 'Command completed successfully; action pending' response[:results][0][:msg].should == 'Command completed successfully; action pending'
response[:results][0][:result_code].should == '1001' response[:results][0][:result_code].should == '1001'
@ -1736,7 +1737,7 @@ describe 'EPP Domain', epp: true do
}] }]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:results][0][:result_code].should == '2306' response[:results][0][:result_code].should == '2306'
response[:results][0][:msg].should == "Parameter value policy error. Client-side object status "\ response[:results][0][:msg].should == "Parameter value policy error. Client-side object status "\
"management not supported: status [status]" "management not supported: status [status]"
@ -1788,7 +1789,7 @@ describe 'EPP Domain', epp: true do
] ]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:results][0][:msg].should == 'Command completed successfully' response[:results][0][:msg].should == 'Command completed successfully'
response[:results][0][:result_code].should == '1000' response[:results][0][:result_code].should == '1000'
@ -1815,13 +1816,16 @@ describe 'EPP Domain', epp: true do
}, { }, {
rem: [ rem: [
{ keyData: { { keyData: {
flags: { value: '256' },
protocol: { value: '3' },
alg: { value: '254' },
pubKey: { value: '700b97b591ed27ec2590d19f06f88bba700b97b591ed27ec2590d19f' } pubKey: { value: '700b97b591ed27ec2590d19f06f88bba700b97b591ed27ec2590d19f' }
} }
} }
] ]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:results][0][:msg].should == 'Command completed successfully' response[:results][0][:msg].should == 'Command completed successfully'
response[:results][0][:result_code].should == '1000' response[:results][0][:result_code].should == '1000'
@ -1836,7 +1840,7 @@ describe 'EPP Domain', epp: true do
rem_cnt = d.tech_contacts.find_by(code: 'FIXED:CITIZEN_1234') rem_cnt = d.tech_contacts.find_by(code: 'FIXED:CITIZEN_1234')
rem_cnt.should be_falsey rem_cnt.should be_falsey
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:results][0][:result_code].should == '2303' response[:results][0][:result_code].should == '2303'
response[:results][0][:msg].should == 'Nameserver was not found' response[:results][0][:msg].should == 'Nameserver was not found'
@ -1864,7 +1868,7 @@ describe 'EPP Domain', epp: true do
] ]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:results][0][:result_code].should == '2303' response[:results][0][:result_code].should == '2303'
response[:results][0][:msg].should == 'Status was not found' response[:results][0][:msg].should == 'Status was not found'
@ -1892,8 +1896,8 @@ describe 'EPP Domain', epp: true do
} }
}) })
epp_plain_request(xml, :xml) epp_plain_request(xml)
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:results][0][:result_code].should == '2302' response[:results][0][:result_code].should == '2302'
response[:results][0][:msg].should == 'Nameserver already exists on this domain [hostname]' response[:results][0][:msg].should == 'Nameserver already exists on this domain [hostname]'
@ -1912,7 +1916,7 @@ describe 'EPP Domain', epp: true do
] ]
} }
response = epp_plain_request(domain_update_xml(xml_params), :xml) response = epp_plain_request(domain_update_xml(xml_params))
response[:results][0][:msg].should == response[:results][0][:msg].should ==
'Required parameter missing: extension > extdata > legalDocument [legal_document]' 'Required parameter missing: extension > extdata > legalDocument [legal_document]'
response[:results][0][:result_code].should == '2003' response[:results][0][:result_code].should == '2003'
@ -1926,7 +1930,7 @@ describe 'EPP Domain', epp: true do
] ]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml, validate_input: false)
response[:results][0][:result_code].should == '2303' response[:results][0][:result_code].should == '2303'
response[:results][0][:msg].should == 'Status was not found' response[:results][0][:msg].should == 'Status was not found'
response[:results][0][:value].should == 'invalidStatus' response[:results][0][:value].should == 'invalidStatus'
@ -1941,7 +1945,7 @@ describe 'EPP Domain', epp: true do
period: { value: '1', attrs: { unit: 'y' } } period: { value: '1', attrs: { unit: 'y' } }
) )
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:results][0][:msg].should == 'Command completed successfully' response[:results][0][:msg].should == 'Command completed successfully'
response[:results][0][:result_code].should == '1000' response[:results][0][:result_code].should == '1000'
@ -1958,7 +1962,7 @@ describe 'EPP Domain', epp: true do
period: { value: '1', attrs: { unit: 'y' } } period: { value: '1', attrs: { unit: 'y' } }
) )
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:results][0][:result_code].should == '2306' response[:results][0][:result_code].should == '2306'
response[:results][0][:msg].should == 'Given and current expire dates do not match' response[:results][0][:msg].should == 'Given and current expire dates do not match'
end end
@ -1972,7 +1976,7 @@ describe 'EPP Domain', epp: true do
period: { value: '4', attrs: { unit: 'y' } } period: { value: '4', attrs: { unit: 'y' } }
) )
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:results][0][:msg].should == 'Period must add up to 1, 2 or 3 years [period]' response[:results][0][:msg].should == 'Period must add up to 1, 2 or 3 years [period]'
response[:results][0][:result_code].should == '2004' response[:results][0][:result_code].should == '2004'
response[:results][0][:value].should == '4' response[:results][0][:value].should == '4'
@ -1987,7 +1991,7 @@ describe 'EPP Domain', epp: true do
ds_key_tag: '123', ds_key_tag: '123',
ds_alg: 3, ds_alg: 3,
ds_digest_type: 1, ds_digest_type: 1,
ds_digest: 'abc', ds_digest: '0D85A305D22FCB355BBE29AE9809363D697B64782B9CC73AE349350F8C2AE4BB',
flags: 257, flags: 257,
protocol: 3, protocol: 3,
alg: 3, alg: 3,
@ -1998,7 +2002,7 @@ describe 'EPP Domain', epp: true do
ds_key_tag: '123', ds_key_tag: '123',
ds_alg: 3, ds_alg: 3,
ds_digest_type: 1, ds_digest_type: 1,
ds_digest: 'abc', ds_digest: '0D85A305D22FCB355BBE29AE9809363D697B64782B9CC73AE349350F8C2AE4BB',
flags: 0, flags: 0,
protocol: 3, protocol: 3,
alg: 5, alg: 5,
@ -2008,7 +2012,7 @@ describe 'EPP Domain', epp: true do
domain.save domain.save
xml = domain_info_xml(name: { value: domain.name }) xml = domain_info_xml(name: { value: domain.name })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:results][0][:msg].should == 'Command completed successfully' response[:results][0][:msg].should == 'Command completed successfully'
response[:results][0][:result_code].should == '1000' response[:results][0][:result_code].should == '1000'
response[:clTRID].should be_nil response[:clTRID].should be_nil
@ -2018,6 +2022,7 @@ describe 'EPP Domain', epp: true do
inf_data.css('status').text.should == 'Payment overdue.' inf_data.css('status').text.should == 'Payment overdue.'
inf_data.css('status').first[:s].should == 'clientHold' inf_data.css('status').first[:s].should == 'clientHold'
inf_data.css('registrant').text.should == domain.registrant_code inf_data.css('registrant').text.should == domain.registrant_code
inf_data.css('roid').text.should == domain.roid
admin_contacts_from_request = inf_data.css('contact[type="admin"]').map(&:text) admin_contacts_from_request = inf_data.css('contact[type="admin"]').map(&:text)
admin_contacts_existing = domain.admin_contacts.pluck(:code) admin_contacts_existing = domain.admin_contacts.pluck(:code)
@ -2043,7 +2048,7 @@ describe 'EPP Domain', epp: true do
ds_data_1.css('keyTag').first.text.should == '123' ds_data_1.css('keyTag').first.text.should == '123'
ds_data_1.css('alg').first.text.should == '3' ds_data_1.css('alg').first.text.should == '3'
ds_data_1.css('digestType').first.text.should == '1' ds_data_1.css('digestType').first.text.should == '1'
ds_data_1.css('digest').first.text.should == 'abc' ds_data_1.css('digest').first.text.should == '0D85A305D22FCB355BBE29AE9809363D697B64782B9CC73AE349350F8C2AE4BB'
dnskey_1 = ds_data_1.css('keyData')[0] dnskey_1 = ds_data_1.css('keyData')[0]
dnskey_1.css('flags').first.text.should == '257' dnskey_1.css('flags').first.text.should == '257'
@ -2061,7 +2066,7 @@ describe 'EPP Domain', epp: true do
domain.touch domain.touch
response = epp_plain_request(domain_info_xml(name: { value: domain.name }), :xml) response = epp_plain_request(domain_info_xml(name: { value: domain.name }))
inf_data = response[:parsed].css('resData infData') inf_data = response[:parsed].css('resData infData')
inf_data.css('upDate').text.should == domain.updated_at.to_time.utc.iso8601 inf_data.css('upDate').text.should == domain.updated_at.to_time.utc.iso8601
@ -2076,13 +2081,13 @@ describe 'EPP Domain', epp: true do
domain.nameservers.build(hostname: "ns3.test.ee", ipv4: '192.168.1.1', ipv6: '1080:0:0:0:8:800:200C:417A') domain.nameservers.build(hostname: "ns3.test.ee", ipv4: '192.168.1.1', ipv6: '1080:0:0:0:8:800:200C:417A')
domain.save domain.save
xml = domain_info_xml(name: { value: domain.name, attrs: { hosts: 'inalid' } }) xml = domain_info_xml(name: { value: domain.name, attrs: { hosts: 'invalid' } })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml, validate_input: false)
response[:msg].should == 'Attribute is invalid: hosts' response[:msg].should == 'Attribute is invalid: hosts'
response[:result_code].should == '2306' response[:result_code].should == '2306'
xml = domain_info_xml(name: { value: domain.name, attrs: { hosts: 'sub' } }) xml = domain_info_xml(name: { value: domain.name, attrs: { hosts: 'sub' } })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
inf_data = response[:parsed].css('resData infData') inf_data = response[:parsed].css('resData infData')
inf_data.css('hostAttr').count.should == 2 inf_data.css('hostAttr').count.should == 2
@ -2090,41 +2095,41 @@ describe 'EPP Domain', epp: true do
inf_data.css('hostName').last.text.should == "ns2.#{domain.name}" inf_data.css('hostName').last.text.should == "ns2.#{domain.name}"
xml = domain_info_xml(name: { value: domain.name, attrs: { hosts: 'del' } }) xml = domain_info_xml(name: { value: domain.name, attrs: { hosts: 'del' } })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
inf_data = response[:parsed].css('resData infData') inf_data = response[:parsed].css('resData infData')
inf_data.css('hostAttr').count.should == 1 inf_data.css('hostAttr').count.should == 1
inf_data.css('hostName').first.text.should == "ns3.test.ee" inf_data.css('hostName').first.text.should == "ns3.test.ee"
xml = domain_info_xml(name: { value: domain.name, attrs: { hosts: 'none' } }) xml = domain_info_xml(name: { value: domain.name, attrs: { hosts: 'none' } })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
inf_data = response[:parsed].css('resData infData') inf_data = response[:parsed].css('resData infData')
inf_data.css('ns').count.should == 0 inf_data.css('ns').count.should == 0
inf_data.css('hostAttr').count.should == 0 inf_data.css('hostAttr').count.should == 0
xml = domain_info_xml(name: { value: domain.name, attrs: { hosts: 'all' } }) xml = domain_info_xml(name: { value: domain.name, attrs: { hosts: 'all' } })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
inf_data = response[:parsed].css('resData infData') inf_data = response[:parsed].css('resData infData')
inf_data.css('hostAttr').count.should == 3 inf_data.css('hostAttr').count.should == 3
end end
it 'returns error when domain can not be found' do it 'returns error when domain can not be found' do
response = epp_plain_request(domain_info_xml(name: { value: 'test.ee' }), :xml) response = epp_plain_request(domain_info_xml(name: { value: 'test.ee' }))
response[:results][0][:result_code].should == '2303' response[:results][0][:result_code].should == '2303'
response[:results][0][:msg].should == 'Domain not found' response[:results][0][:msg].should == 'Domain not found'
end end
it 'sets ok status by default' do it 'sets ok status by default' do
response = epp_plain_request(domain_info_xml(name: { value: domain.name }), :xml) response = epp_plain_request(domain_info_xml(name: { value: domain.name }))
inf_data = response[:parsed].css('resData infData') inf_data = response[:parsed].css('resData infData')
inf_data.css('status').first[:s].should == 'ok' inf_data.css('status').first[:s].should == 'ok'
end end
it 'can not see other registrar domains with invalid password' do it 'can not see other registrar domains with invalid password' do
login_as :registrar2 do login_as :registrar2 do
response = epp_plain_request(domain_info_xml(name: { value: domain.name }), :xml) response = epp_plain_request(domain_info_xml(name: { value: domain.name }))
response[:result_code].should == '2201' response[:result_code].should == '2201'
response[:msg].should == 'Authorization error' response[:msg].should == 'Authorization error'
end end
@ -2135,7 +2140,7 @@ describe 'EPP Domain', epp: true do
response = epp_plain_request(domain_info_xml( response = epp_plain_request(domain_info_xml(
name: { value: domain.name }, name: { value: domain.name },
authInfo: nil authInfo: nil
), :xml) ))
response[:result_code].should == '1000' response[:result_code].should == '1000'
response[:parsed].css('authInfo pw').first.should == nil response[:parsed].css('authInfo pw').first.should == nil
@ -2148,7 +2153,7 @@ describe 'EPP Domain', epp: true do
response = epp_plain_request(domain_info_xml( response = epp_plain_request(domain_info_xml(
name: { value: domain.name }, name: { value: domain.name },
authInfo: { pw: { value: pw } } authInfo: { pw: { value: pw } }
), :xml) ))
response[:result_code].should == '1000' response[:result_code].should == '1000'
response[:parsed].css('authInfo pw').text.should == pw response[:parsed].css('authInfo pw').text.should == pw
@ -2162,11 +2167,11 @@ describe 'EPP Domain', epp: true do
}, { }, {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
}), :xml) }))
response[:msg].should == 'Command completed successfully; action pending' response[:msg].should == 'Command completed successfully; action pending'
response[:result_code].should == '1001' response[:result_code].should == '1001'
@ -2182,11 +2187,11 @@ describe 'EPP Domain', epp: true do
}, { }, {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
}), :xml) }))
response[:result_code].should == '2304' response[:result_code].should == '2304'
response[:msg].should == 'Domain status prohibits operation' response[:msg].should == 'Domain status prohibits operation'
@ -2200,18 +2205,18 @@ describe 'EPP Domain', epp: true do
}, { }, {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
}), :xml) }))
response[:msg].should == 'Object status prohibits operation' response[:msg].should == 'Object status prohibits operation'
response[:result_code].should == '2304' response[:result_code].should == '2304'
end end
it 'does not delete domain without legal document' do it 'does not delete domain without legal document' do
response = epp_plain_request(@epp_xml.domain.delete(name: { value: 'example.ee' }), :xml) response = epp_plain_request(@epp_xml.domain.delete(name: { value: 'example.ee' }))
response[:result_code].should == '2003' response[:result_code].should == '2003'
response[:msg].should == response[:msg].should ==
'Required parameter missing: extension > extdata > legalDocument [legal_document]' 'Required parameter missing: extension > extdata > legalDocument [legal_document]'
@ -2223,7 +2228,7 @@ describe 'EPP Domain', epp: true do
_anonymus: [ _anonymus: [
{ name: { value: 'one.ee' } } { name: { value: 'one.ee' } }
] ]
}), :xml) }))
response[:result_code].should == '1000' response[:result_code].should == '1000'
response[:msg].should == 'Command completed successfully' response[:msg].should == 'Command completed successfully'
@ -2236,7 +2241,7 @@ describe 'EPP Domain', epp: true do
_anonymus: [ _anonymus: [
{ name: { value: domain.name } } { name: { value: domain.name } }
] ]
}), :xml) }))
res_data = response[:parsed].css('resData chkData cd').first res_data = response[:parsed].css('resData chkData cd').first
name = res_data.css('name').first name = res_data.css('name').first
reason = res_data.css('reason').first reason = res_data.css('reason').first
@ -2255,7 +2260,7 @@ describe 'EPP Domain', epp: true do
] ]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:result_code].should == '1000' response[:result_code].should == '1000'
response[:msg].should == 'Command completed successfully' response[:msg].should == 'Command completed successfully'
@ -2276,7 +2281,7 @@ describe 'EPP Domain', epp: true do
] ]
}) })
response = epp_plain_request(xml, :xml) response = epp_plain_request(xml)
response[:result_code].should == '1000' response[:result_code].should == '1000'
response[:msg].should == 'Command completed successfully' response[:msg].should == 'Command completed successfully'

View file

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<renew>
<contact:renew
xmlns:contact="urn:ietf:params:xml:ns:contact-1.0">
<contact:id>info-4444</contact:id>
<contact:authInfo>
<contact:pw>2fooBAR</contact:pw>
</contact:authInfo>
</contact:renew>
</renew>
<clTRID>ABC-12345</clTRID>
</command>
</epp>

View file

@ -5,6 +5,7 @@ describe 'EPP Session', epp: true do
@api_user = Fabricate(:gitlab_api_user) @api_user = Fabricate(:gitlab_api_user)
@epp_xml = EppXml.new(cl_trid: 'ABC-12345') @epp_xml = EppXml.new(cl_trid: 'ABC-12345')
@login_xml_cache = @epp_xml.session.login(clID: { value: 'gitlab' }, pw: { value: 'ghyt9e4fu' }) @login_xml_cache = @epp_xml.session.login(clID: { value: 'gitlab' }, pw: { value: 'ghyt9e4fu' })
@xsd = Nokogiri::XML::Schema(File.read('doc/schemas/epp-1.0.xsd'))
end end
context 'when not connected' do context 'when not connected' do
@ -23,7 +24,7 @@ describe 'EPP Session', epp: true do
it 'does not log in with invalid user' do it 'does not log in with invalid user' do
wrong_user = @epp_xml.session.login(clID: { value: 'wrong-user' }, pw: { value: 'ghyt9e4fu' }) wrong_user = @epp_xml.session.login(clID: { value: 'wrong-user' }, pw: { value: 'ghyt9e4fu' })
response = epp_plain_request(wrong_user, :xml) response = epp_plain_request(wrong_user)
response[:msg].should == 'Authentication error; server closing connection' response[:msg].should == 'Authentication error; server closing connection'
response[:result_code].should == '2501' response[:result_code].should == '2501'
response[:clTRID].should == 'ABC-12345' response[:clTRID].should == 'ABC-12345'
@ -34,28 +35,29 @@ describe 'EPP Session', epp: true do
Fabricate(:api_user, username: 'inactive-user', active: false, registrar: @registrar) Fabricate(:api_user, username: 'inactive-user', active: false, registrar: @registrar)
inactive = @epp_xml.session.login(clID: { value: 'inactive-user' }, pw: { value: 'ghyt9e4fu' }) inactive = @epp_xml.session.login(clID: { value: 'inactive-user' }, pw: { value: 'ghyt9e4fu' })
response = epp_plain_request(inactive, :xml) response = epp_plain_request(inactive)
response[:msg].should == 'Authentication error; server closing connection' response[:msg].should == 'Authentication error; server closing connection'
response[:result_code].should == '2501' response[:result_code].should == '2501'
end end
it 'prohibits further actions unless logged in' do it 'prohibits further actions unless logged in' do
response = epp_plain_request(@epp_xml.domain.create, :xml) @xsd = Nokogiri::XML::Schema(File.read('doc/schemas/domain-1.0.xsd'))
response = epp_plain_request(@epp_xml.domain.info(name: { value: 'test.ee' }))
response[:msg].should == 'You need to login first.' response[:msg].should == 'You need to login first.'
response[:result_code].should == '2002' response[:result_code].should == '2002'
response[:clTRID].should == 'ABC-12345' response[:clTRID].should == 'ABC-12345'
end end
it 'should not have clTRID in response if client does not send it' do it 'should not have clTRID in response if client does not send it' do
epp_xml_no_cltrid = EppXml.new(cl_trid: '') epp_xml_no_cltrid = EppXml.new(cl_trid: false)
wrong_user = epp_xml_no_cltrid.session.login(clID: { value: 'wrong-user' }, pw: { value: 'ghyt9e4fu' }) wrong_user = epp_xml_no_cltrid.session.login(clID: { value: 'wrong-user' }, pw: { value: 'ghyt9e4fu' })
response = epp_plain_request(wrong_user, :xml) response = epp_plain_request(wrong_user)
response[:clTRID].should be_nil response[:clTRID].should be_nil
end end
context 'with valid user' do context 'with valid user' do
it 'logs in epp user' do it 'logs in epp user' do
response = epp_plain_request(@login_xml_cache, :xml) response = epp_plain_request(@login_xml_cache)
response[:msg].should == 'Command completed successfully' response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000' response[:result_code].should == '1000'
response[:clTRID].should == 'ABC-12345' response[:clTRID].should == 'ABC-12345'
@ -67,12 +69,12 @@ describe 'EPP Session', epp: true do
end end
it 'does not log in twice' do it 'does not log in twice' do
response = epp_plain_request(@login_xml_cache, :xml) response = epp_plain_request(@login_xml_cache)
response[:msg].should == 'Command completed successfully' response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000' response[:result_code].should == '1000'
response[:clTRID].should == 'ABC-12345' response[:clTRID].should == 'ABC-12345'
response = epp_plain_request(@login_xml_cache, :xml) response = epp_plain_request(@login_xml_cache)
response[:msg].should match(/Already logged in. Use/) response[:msg].should match(/Already logged in. Use/)
response[:result_code].should == '2002' response[:result_code].should == '2002'
@ -84,10 +86,10 @@ describe 'EPP Session', epp: true do
it 'logs out epp user' do it 'logs out epp user' do
c = EppSession.count c = EppSession.count
epp_plain_request(@login_xml_cache, :xml) epp_plain_request(@login_xml_cache)
EppSession.count.should == c + 1 EppSession.count.should == c + 1
response = epp_plain_request(@epp_xml.session.logout, :xml) response = epp_plain_request(@epp_xml.session.logout)
response[:msg].should == 'Command completed successfully; ending session' response[:msg].should == 'Command completed successfully; ending session'
response[:result_code].should == '1500' response[:result_code].should == '1500'
@ -100,7 +102,7 @@ describe 'EPP Session', epp: true do
clID: { value: 'gitlab' }, clID: { value: 'gitlab' },
pw: { value: 'ghyt9e4fu' }, pw: { value: 'ghyt9e4fu' },
newPW: { value: 'abcdefg' } newPW: { value: 'abcdefg' }
), :xml) ))
response[:msg].should == 'Command completed successfully' response[:msg].should == 'Command completed successfully'
response[:result_code].should == '1000' response[:result_code].should == '1000'
@ -115,7 +117,22 @@ describe 'EPP Session', epp: true do
clID: { value: 'gitlab' }, clID: { value: 'gitlab' },
pw: { value: 'ghyt9e4fu' }, pw: { value: 'ghyt9e4fu' },
newPW: { value: '' } newPW: { value: '' }
), :xml) ), validate_input: false)
response[:msg].should == 'Password is missing [password]'
response[:result_code].should == '2306'
@api_user.reload
@api_user.password.should == 'ghyt9e4fu'
end
it 'fails if new password is not valid' do
@api_user.update(password: 'ghyt9e4fu')
response = epp_plain_request(@epp_xml.session.login(
clID: { value: 'gitlab' },
pw: { value: 'ghyt9e4fu' },
newPW: { value: '' }
), validate_input: false)
response[:msg].should == 'Password is missing [password]' response[:msg].should == 'Password is missing [password]'
response[:result_code].should == '2306' response[:result_code].should == '2306'

View file

@ -66,15 +66,27 @@ module Epp
end end
def epp_plain_request(data, *args) def epp_plain_request(data, *args)
res = parse_response(server.send_request(data)) if args.include?(:xml) options = args.extract_options!
if res validate_input = options[:validate_input] != false # true by default
log(data, res[:parsed]) validate_output = options[:validate_output] != false # true by default
return res
if validate_input && @xsd
xml = Nokogiri::XML(data)
@xsd.validate(xml).each do |error|
fail Exception.new, error.to_s
end
end end
res = parse_response(server.send_request(read_body(data))) res = parse_response(server.send_request(data))
log(read_body(data), res[:parsed]) if res
log(data, res[:parsed])
if validate_output && @xsd
@xsd.validate(Nokogiri(res[:raw])).each do |error|
fail Exception.new, error.to_s
end
end
return res return res
end
rescue => e rescue => e
e e
end end
@ -127,7 +139,7 @@ module Epp
xml_params = defaults.deep_merge(xml_params) xml_params = defaults.deep_merge(xml_params)
epp_xml = EppXml::Domain.new(cl_trid: '') epp_xml = EppXml::Domain.new(cl_trid: false)
epp_xml.info(xml_params) epp_xml.info(xml_params)
end end
@ -176,7 +188,7 @@ module Epp
custom_params = { custom_params = {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
@ -219,7 +231,7 @@ module Epp
epp_xml.create(xml_params, {}, { epp_xml.create(xml_params, {}, {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
@ -260,7 +272,7 @@ module Epp
custom_params = { custom_params = {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]
@ -304,7 +316,7 @@ module Epp
custom_params = { custom_params = {
_anonymus: [ _anonymus: [
legalDocument: { legalDocument: {
value: 'JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0Zp==', value: 'dGVzdCBmYWlsCg==',
attrs: { type: 'pdf' } attrs: { type: 'pdf' }
} }
] ]