mirror of
https://github.com/instant-labs/instant-epp.git
synced 2025-01-19 08:09:03 +00:00
add RFC8590 implementation
Implements the Change Poll Extension for the Extensible Provisioning Protocol. Test cases are taken from the spec.
This commit is contained in:
parent
fac8c173c9
commit
2188df56c3
359
src/extensions/change_poll.rs
Normal file
359
src/extensions/change_poll.rs
Normal file
@ -0,0 +1,359 @@
|
||||
//! Types for the EPP change poll extention
|
||||
//!
|
||||
//! As described in RFC8590: [Change Poll Extension for the Extensible Provisioning Protocol (EPP)](https://www.rfc-editor.org/rfc/rfc8590.html).
|
||||
//! Tests cases in `tests/resources/response/extensions/changepoll`` are taken from the RFC.
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
||||
use instant_xml::{Error, FromXml, ToXml};
|
||||
|
||||
use crate::{
|
||||
poll::Poll,
|
||||
request::{Extension, Transaction},
|
||||
};
|
||||
|
||||
pub const XMLNS: &str = "urn:ietf:params:xml:ns:changePoll-1.0";
|
||||
|
||||
impl Transaction<ChangePoll<'_>> for Poll {}
|
||||
|
||||
impl Extension for ChangePoll<'_> {
|
||||
type Response = ChangePoll<'static>;
|
||||
}
|
||||
|
||||
/// Type for EPP XML `<changePoll>` extension
|
||||
///
|
||||
/// Attributes associated with the change
|
||||
#[derive(Debug, FromXml, ToXml)]
|
||||
#[xml(rename = "changeData", ns(XMLNS))]
|
||||
pub struct ChangePoll<'a> {
|
||||
/// Transform operation executed on the object
|
||||
pub operation: Operation<'a>,
|
||||
/// Date and time when the operation was executed
|
||||
pub date: Cow<'a, str>,
|
||||
/// Server transaction identifier of the operation
|
||||
#[xml(rename = "svTRID")]
|
||||
pub server_tr_id: Cow<'a, str>,
|
||||
/// Who executed the operation
|
||||
pub who: Cow<'a, str>,
|
||||
/// Case identifier associated with the operation
|
||||
pub case_id: Option<CaseIdentifier<'a>>,
|
||||
/// Reason for executing the operation
|
||||
pub reason: Option<Reason>,
|
||||
/// Enumerated state of the object in the poll message
|
||||
#[xml(attribute)]
|
||||
// todo: State should utilize the Default impl,
|
||||
// but instant-xml does not support it yet.
|
||||
state: Option<State>,
|
||||
}
|
||||
|
||||
impl ChangePoll<'_> {
|
||||
/// State reflects if the `infData` describes the object before or after the operation
|
||||
pub fn state(&self) -> State {
|
||||
self.state.unwrap_or_default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Transform operation type for `<changePoll:operation>`
|
||||
// todo: Allow struct enum variants with #[xml(attribute, rename = "op")] in instant-xml,
|
||||
// to make this struct more ergonomic.
|
||||
#[derive(Debug, FromXml, ToXml)]
|
||||
#[xml(rename = "operation", ns(XMLNS))]
|
||||
pub struct Operation<'a> {
|
||||
/// Custom value for`OperationKind::Custom`
|
||||
#[xml(attribute, rename = "op")]
|
||||
op: Option<Cow<'a, str>>,
|
||||
/// The operation
|
||||
#[xml(direct)]
|
||||
kind: OperationType,
|
||||
}
|
||||
|
||||
impl Operation<'_> {
|
||||
pub fn kind(&self) -> Result<OperationKind, Error> {
|
||||
Ok(match self.kind {
|
||||
OperationType::Create => OperationKind::Create,
|
||||
OperationType::Delete => OperationKind::Delete,
|
||||
OperationType::Renew => OperationKind::Renew,
|
||||
OperationType::Transfer => OperationKind::Transfer,
|
||||
OperationType::Update => OperationKind::Update,
|
||||
OperationType::Restore => OperationKind::Restore,
|
||||
OperationType::AutoRenew => OperationKind::AutoRenew,
|
||||
OperationType::AutoDelete => OperationKind::AutoDelete,
|
||||
OperationType::AutoPurge => OperationKind::AutoPurge,
|
||||
OperationType::Custom => match self.op.as_deref() {
|
||||
Some(op) => OperationKind::Custom(op),
|
||||
None => {
|
||||
return Err(Error::Other(
|
||||
"invariant error: Missing op attribute for custom operation".to_string(),
|
||||
))
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Enumerated list of operations
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum OperationKind<'a> {
|
||||
Create,
|
||||
Delete,
|
||||
Renew,
|
||||
Transfer,
|
||||
Update,
|
||||
Restore,
|
||||
AutoRenew,
|
||||
AutoDelete,
|
||||
AutoPurge,
|
||||
Custom(&'a str),
|
||||
}
|
||||
|
||||
/// Internal Enumerated list of operations, with extensibility via "custom"
|
||||
// See todo on `Operation` struct for reason why this is internal only.
|
||||
#[derive(Debug, Copy, Clone, FromXml, ToXml)]
|
||||
#[xml(scalar, rename_all = "camelCase", ns(XMLNS))]
|
||||
enum OperationType {
|
||||
Create,
|
||||
Delete,
|
||||
Renew,
|
||||
Transfer,
|
||||
Update,
|
||||
Restore,
|
||||
AutoRenew,
|
||||
AutoDelete,
|
||||
AutoPurge,
|
||||
Custom,
|
||||
}
|
||||
|
||||
/// Case identifier type for `<changePoll:caseId>`
|
||||
// todo: Allow struct enum variants with #[xml(attribute, rename = "op")] in instant-xml,
|
||||
// to make this struct more ergonomic.
|
||||
#[derive(Debug, FromXml, ToXml)]
|
||||
#[xml(rename = "caseId", ns(XMLNS))]
|
||||
pub struct CaseIdentifier<'a> {
|
||||
#[xml(attribute, rename = "type")]
|
||||
id_type: CaseIdentifierType,
|
||||
#[xml(attribute)]
|
||||
name: Option<Cow<'a, str>>,
|
||||
#[xml(direct)]
|
||||
pub id: Cow<'a, str>,
|
||||
}
|
||||
|
||||
impl CaseIdentifier<'_> {
|
||||
pub fn kind(&self) -> Result<CaseIdentifierKind, Error> {
|
||||
Ok(match self.id_type {
|
||||
CaseIdentifierType::Udrp => CaseIdentifierKind::Udrp,
|
||||
CaseIdentifierType::Urs => CaseIdentifierKind::Urs,
|
||||
CaseIdentifierType::Custom => match self.name.as_deref() {
|
||||
Some(name) => CaseIdentifierKind::Custom(name),
|
||||
None => {
|
||||
return Err(Error::Other(
|
||||
"invariant error: Missing name attribute for custom case identifier"
|
||||
.to_string(),
|
||||
))
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum CaseIdentifierKind<'a> {
|
||||
Udrp,
|
||||
Urs,
|
||||
Custom(&'a str),
|
||||
}
|
||||
|
||||
/// Internal enumerated list of case identifier types
|
||||
// See todo on `CaseIdentifier` struct for reason why this is internal only.
|
||||
#[derive(Debug, Copy, Clone, FromXml, ToXml)]
|
||||
#[xml(scalar, rename_all = "camelCase")]
|
||||
enum CaseIdentifierType {
|
||||
Udrp,
|
||||
Urs,
|
||||
Custom,
|
||||
}
|
||||
|
||||
/// Reason type for `<changePoll:reason>`
|
||||
///
|
||||
/// A human-readable message that describes the reason for the encapsulating element.
|
||||
/// The language of the response is identified via the "lang" attribute.
|
||||
///
|
||||
/// Schema defined in the `eppcom-1.0` XML schema
|
||||
// todo: while this is defined in `eppcom` schema, it is used with different
|
||||
// namespaces in additional specs (for example in RFC8590).
|
||||
// Currently, instant-xml strongly ties namespaces to schemas and does not allow
|
||||
// a way out of it for this particular case.
|
||||
#[derive(Debug, Eq, FromXml, PartialEq, ToXml)]
|
||||
#[xml(rename = "reason", ns(XMLNS))]
|
||||
pub struct Reason {
|
||||
/// The language of the response. If not specified, assume "en" (English).
|
||||
#[xml(attribute)]
|
||||
pub lang: Option<String>,
|
||||
#[xml(direct)]
|
||||
pub inner: String,
|
||||
}
|
||||
|
||||
/// Enumerated state of the object in the poll message
|
||||
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, FromXml, ToXml)]
|
||||
#[xml(scalar, rename_all = "camelCase")]
|
||||
pub enum State {
|
||||
Before,
|
||||
#[default]
|
||||
After,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::poll::Poll;
|
||||
use crate::response::ResultCode;
|
||||
use crate::tests::{response_from_file_with_ext, CLTRID, SVTRID};
|
||||
|
||||
#[test]
|
||||
fn urs_lock_before() {
|
||||
let object = response_from_file_with_ext::<Poll, ChangePoll>(
|
||||
"response/extensions/change_poll/urs_lock_before.xml",
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
object.result.code,
|
||||
ResultCode::CommandCompletedSuccessfullyAckToDequeue
|
||||
);
|
||||
assert_eq!(
|
||||
object.result.message,
|
||||
"Command completed successfully; ack to dequeue"
|
||||
);
|
||||
|
||||
assert_eq!(object.extension().unwrap().state.unwrap(), State::Before);
|
||||
assert_eq!(
|
||||
object.extension().unwrap().operation.kind().unwrap(),
|
||||
OperationKind::Update
|
||||
);
|
||||
assert_eq!(object.extension().unwrap().date, "2013-10-22T14:25:57.0Z");
|
||||
assert_eq!(object.extension().unwrap().server_tr_id, "12345-XYZ");
|
||||
assert_eq!(object.extension().unwrap().who, "URS Admin");
|
||||
assert_eq!(
|
||||
object
|
||||
.extension()
|
||||
.unwrap()
|
||||
.case_id
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.kind()
|
||||
.unwrap(),
|
||||
CaseIdentifierKind::Urs
|
||||
);
|
||||
assert_eq!(
|
||||
object.extension().unwrap().reason.as_ref().unwrap().inner,
|
||||
"URS Lock"
|
||||
);
|
||||
|
||||
assert_eq!(object.tr_ids.client_tr_id.unwrap(), CLTRID);
|
||||
assert_eq!(object.tr_ids.server_tr_id, SVTRID);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn urs_lock_after() {
|
||||
let object = response_from_file_with_ext::<Poll, ChangePoll>(
|
||||
"response/extensions/change_poll/urs_lock_after.xml",
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
object.result.code,
|
||||
ResultCode::CommandCompletedSuccessfullyAckToDequeue
|
||||
);
|
||||
assert_eq!(
|
||||
object.result.message,
|
||||
"Command completed successfully; ack to dequeue"
|
||||
);
|
||||
assert_eq!(object.extension().unwrap().state.unwrap(), State::After);
|
||||
|
||||
assert_eq!(object.tr_ids.client_tr_id.unwrap(), CLTRID);
|
||||
assert_eq!(object.tr_ids.server_tr_id, SVTRID);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_sync_after() {
|
||||
let object = response_from_file_with_ext::<Poll, ChangePoll>(
|
||||
"response/extensions/change_poll/custom_sync_after.xml",
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
object.result.code,
|
||||
ResultCode::CommandCompletedSuccessfullyAckToDequeue
|
||||
);
|
||||
assert_eq!(
|
||||
object.result.message,
|
||||
"Command completed successfully; ack to dequeue"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
object.extension().unwrap().operation.kind().unwrap(),
|
||||
OperationKind::Custom("sync")
|
||||
);
|
||||
assert_eq!(object.extension().unwrap().who, "CSR");
|
||||
assert_eq!(
|
||||
object.extension().unwrap().reason.as_ref().unwrap().inner,
|
||||
"Customer sync request"
|
||||
);
|
||||
|
||||
assert_eq!(object.tr_ids.client_tr_id.unwrap(), CLTRID);
|
||||
assert_eq!(object.tr_ids.server_tr_id, SVTRID);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn delete_before() {
|
||||
let object = response_from_file_with_ext::<Poll, ChangePoll>(
|
||||
"response/extensions/change_poll/delete_before.xml",
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
object.result.code,
|
||||
ResultCode::CommandCompletedSuccessfullyAckToDequeue
|
||||
);
|
||||
assert_eq!(
|
||||
object.result.message,
|
||||
"Command completed successfully; ack to dequeue"
|
||||
);
|
||||
|
||||
assert_eq!(object.tr_ids.client_tr_id.unwrap(), CLTRID);
|
||||
assert_eq!(object.tr_ids.server_tr_id, SVTRID);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn autopurge_before() {
|
||||
let object = response_from_file_with_ext::<Poll, ChangePoll>(
|
||||
"response/extensions/change_poll/autopurge_before.xml",
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
object.result.code,
|
||||
ResultCode::CommandCompletedSuccessfullyAckToDequeue
|
||||
);
|
||||
assert_eq!(
|
||||
object.result.message,
|
||||
"Command completed successfully; ack to dequeue"
|
||||
);
|
||||
|
||||
assert_eq!(object.tr_ids.client_tr_id.unwrap(), CLTRID);
|
||||
assert_eq!(object.tr_ids.server_tr_id, SVTRID);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_after() {
|
||||
let object = response_from_file_with_ext::<Poll, ChangePoll>(
|
||||
"response/extensions/change_poll/update_after.xml",
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
object.result.code,
|
||||
ResultCode::CommandCompletedSuccessfullyAckToDequeue
|
||||
);
|
||||
assert_eq!(
|
||||
object.result.message,
|
||||
"Command completed successfully; ack to dequeue"
|
||||
);
|
||||
|
||||
assert_eq!(object.tr_ids.client_tr_id.unwrap(), CLTRID);
|
||||
assert_eq!(object.tr_ids.server_tr_id, SVTRID);
|
||||
}
|
||||
}
|
@ -51,6 +51,7 @@ pub mod response;
|
||||
pub mod xml;
|
||||
|
||||
pub mod extensions {
|
||||
pub mod change_poll;
|
||||
pub mod consolidate;
|
||||
pub mod frnic;
|
||||
pub mod low_balance;
|
||||
|
@ -1,6 +1,7 @@
|
||||
use instant_xml::{FromXml, ToXml};
|
||||
|
||||
use crate::common::{NoExtension, EPP_XMLNS};
|
||||
use crate::domain;
|
||||
use crate::domain::transfer::TransferData;
|
||||
use crate::extensions::low_balance::LowBalance;
|
||||
use crate::extensions::rgp::poll::RgpPollData;
|
||||
@ -61,12 +62,14 @@ impl ToXml for Ack<'_> {
|
||||
|
||||
// Response
|
||||
|
||||
/// Type that represents the `<trnData>` tag for message poll response
|
||||
/// Type that represents the `<resData>` tag for message poll response
|
||||
#[derive(Debug, FromXml)]
|
||||
#[xml(forward)]
|
||||
pub enum PollData {
|
||||
/// Data under the `<domain:trnData>` tag
|
||||
DomainTransfer(TransferData),
|
||||
/// Data under the `<domain:infData>` tag
|
||||
DomainInfo(domain::InfoData),
|
||||
/// Data under the `<host:infData>` tag
|
||||
HostInfo(host::InfoData),
|
||||
/// Data under the `<lowbalance>` tag
|
||||
|
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
An example poll <info> response with the
|
||||
<changePoll:changeData> extension for an "autoPurge" operation on the
|
||||
domain.example domain name that previously had the "pendingDelete"
|
||||
status, with the "before" state. The "before" state is reflected in
|
||||
the <resData> block
|
||||
-->
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<response>
|
||||
<result code="1301">
|
||||
<msg>Command completed successfully; ack to dequeue</msg>
|
||||
</result>
|
||||
<msgQ id="200" count="1">
|
||||
<qDate>2013-10-22T14:25:57.0Z</qDate>
|
||||
<msg>Registry purged domain with pendingDelete status.</msg>
|
||||
</msgQ>
|
||||
<resData>
|
||||
<domain:infData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>domain.example</domain:name>
|
||||
<domain:roid>EXAMPLE1-REP</domain:roid>
|
||||
<domain:status s="pendingDelete"/>
|
||||
<domain:clID>ClientX</domain:clID>
|
||||
</domain:infData>
|
||||
</resData>
|
||||
<extension>
|
||||
<changePoll:changeData xmlns:changePoll="urn:ietf:params:xml:ns:changePoll-1.0" state="before">
|
||||
<changePoll:operation>autoPurge</changePoll:operation>
|
||||
<changePoll:date>2013-10-22T14:25:57.0Z</changePoll:date>
|
||||
<changePoll:svTRID>12345-XYZ</changePoll:svTRID>
|
||||
<changePoll:who>Batch</changePoll:who>
|
||||
<changePoll:reason>Past pendingDelete 5 day period</changePoll:reason>
|
||||
</changePoll:changeData>
|
||||
</extension>
|
||||
<trID>
|
||||
<clTRID>cltrid:1626454866</clTRID>
|
||||
<svTRID>RO-6879-1627224678242975</svTRID>
|
||||
</trID>
|
||||
</response>
|
||||
</epp>
|
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
An example poll <info> response with the
|
||||
<changePoll:changeData> extension for a custom "sync" operation on
|
||||
the domain.example domain name, with the default "after" state. The
|
||||
"after" state is reflected in the <resData> block
|
||||
-->
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<response>
|
||||
<result code="1301">
|
||||
<msg>Command completed successfully; ack to dequeue</msg>
|
||||
</result>
|
||||
<msgQ id="201" count="1">
|
||||
<qDate>2013-10-22T14:25:57.0Z</qDate>
|
||||
<msg>Registry initiated Sync of Domain Expiration Date</msg>
|
||||
</msgQ>
|
||||
<resData>
|
||||
<domain:infData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>domain.example</domain:name>
|
||||
<domain:roid>EXAMPLE1-REP</domain:roid>
|
||||
<domain:status s="ok"/>
|
||||
<domain:registrant>jd1234</domain:registrant>
|
||||
<domain:contact type="admin">sh8013</domain:contact>
|
||||
<domain:contact type="tech">sh8013</domain:contact>
|
||||
<domain:clID>ClientX</domain:clID>
|
||||
<domain:crID>ClientY</domain:crID>
|
||||
<domain:crDate>2012-04-03T22:00:00.0Z</domain:crDate>
|
||||
<domain:upID>ClientZ</domain:upID>
|
||||
<domain:upDate>2013-10-22T14:25:57.0Z</domain:upDate>
|
||||
<domain:exDate>2014-04-03T22:00:00.0Z</domain:exDate>
|
||||
</domain:infData>
|
||||
</resData>
|
||||
<extension>
|
||||
<changePoll:changeData xmlns:changePoll="urn:ietf:params:xml:ns:changePoll-1.0">
|
||||
<changePoll:operation op="sync">custom</changePoll:operation>
|
||||
<changePoll:date>2013-10-22T14:25:57.0Z</changePoll:date>
|
||||
<changePoll:svTRID>12345-XYZ</changePoll:svTRID>
|
||||
<changePoll:who>CSR</changePoll:who>
|
||||
<changePoll:reason lang="en">Customer sync request</changePoll:reason>
|
||||
</changePoll:changeData>
|
||||
</extension>
|
||||
<trID>
|
||||
<clTRID>cltrid:1626454866</clTRID>
|
||||
<svTRID>RO-6879-1627224678242975</svTRID>
|
||||
</trID>
|
||||
</response>
|
||||
</epp>
|
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
An example poll <info> response with the
|
||||
<changePoll:changeData> extension for a "delete" operation on the
|
||||
domain.example domain name that is immediately purged, with the
|
||||
"before" state. The "before" state is reflected in the <resData>
|
||||
block
|
||||
-->
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<response>
|
||||
<result code="1301">
|
||||
<msg>Command completed successfully; ack to dequeue</msg>
|
||||
</result>
|
||||
<msgQ id="200" count="1">
|
||||
<qDate>2013-10-22T14:25:57.0Z</qDate>
|
||||
<msg>Registry initiated delete of domain resulting in immediate purge.</msg>
|
||||
</msgQ>
|
||||
<resData>
|
||||
<domain:infData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>domain.example</domain:name>
|
||||
<domain:roid>EXAMPLE1-REP</domain:roid>
|
||||
<domain:clID>ClientX</domain:clID>
|
||||
</domain:infData>
|
||||
</resData>
|
||||
<extension>
|
||||
<changePoll:changeData xmlns:changePoll="urn:ietf:params:xml:ns:changePoll-1.0" state="before">
|
||||
<changePoll:operation op="purge">delete</changePoll:operation>
|
||||
<changePoll:date>2013-10-22T14:25:57.0Z</changePoll:date>
|
||||
<changePoll:svTRID>12345-XYZ</changePoll:svTRID>
|
||||
<changePoll:who>ClientZ</changePoll:who>
|
||||
<changePoll:reason>Court order</changePoll:reason>
|
||||
</changePoll:changeData>
|
||||
</extension>
|
||||
<trID>
|
||||
<clTRID>cltrid:1626454866</clTRID>
|
||||
<svTRID>RO-6879-1627224678242975</svTRID>
|
||||
</trID>
|
||||
</response>
|
||||
</epp>
|
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
An example poll <info> response with the
|
||||
<changePoll:changeData> extension for an "update" operation on the
|
||||
ns1.domain.example host, with the default "after" state. The "after"
|
||||
state is reflected in the <resData> block
|
||||
-->
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<response>
|
||||
<result code="1301">
|
||||
<msg>Command completed successfully; ack to dequeue</msg>
|
||||
</result>
|
||||
<msgQ id="201" count="1">
|
||||
<qDate>2013-10-22T14:25:57.0Z</qDate>
|
||||
<msg>Registry initiated update of host.</msg>
|
||||
</msgQ>
|
||||
<resData>
|
||||
<host:infData xmlns:host="urn:ietf:params:xml:ns:host-1.0">
|
||||
<host:name>ns1.domain.example</host:name>
|
||||
<host:roid>NS1_EXAMPLE1-REP</host:roid>
|
||||
<host:status s="linked"/>
|
||||
<host:status s="serverUpdateProhibited"/>
|
||||
<host:status s="serverDeleteProhibited"/>
|
||||
<host:addr ip="v4">192.0.2.2</host:addr>
|
||||
<host:addr ip="v6">2001:db8:0:0:1:0:0:1</host:addr>
|
||||
<host:clID>ClientX</host:clID>
|
||||
<host:crID>ClientY</host:crID>
|
||||
<host:crDate>2012-04-03T22:00:00.0Z</host:crDate>
|
||||
<host:upID>ClientY</host:upID>
|
||||
<host:upDate>2013-10-22T14:25:57.0Z</host:upDate>
|
||||
</host:infData>
|
||||
</resData>
|
||||
<extension>
|
||||
<changePoll:changeData xmlns:changePoll="urn:ietf:params:xml:ns:changePoll-1.0">
|
||||
<changePoll:operation>update</changePoll:operation>
|
||||
<changePoll:date>2013-10-22T14:25:57.0Z</changePoll:date>
|
||||
<changePoll:svTRID>12345-XYZ</changePoll:svTRID>
|
||||
<changePoll:who>ClientZ</changePoll:who>
|
||||
<changePoll:reason>Host Lock</changePoll:reason>
|
||||
</changePoll:changeData>
|
||||
</extension>
|
||||
<trID>
|
||||
<clTRID>cltrid:1626454866</clTRID>
|
||||
<svTRID>RO-6879-1627224678242975</svTRID>
|
||||
</trID>
|
||||
</response>
|
||||
</epp>
|
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
An example poll <info> response with the
|
||||
<changePoll:changeData> extension for a URS lock transaction on the
|
||||
domain.example domain name, with the "after" state. The "after"
|
||||
state is reflected in the <resData> block
|
||||
-->
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<response>
|
||||
<result code="1301">
|
||||
<msg lang="en-US">Command completed successfully; ack to dequeue</msg>
|
||||
</result>
|
||||
<msgQ id="202" count="1">
|
||||
<qDate>2013-10-22T14:25:57.0Z</qDate>
|
||||
<msg>Registry initiated update of domain.</msg>
|
||||
</msgQ>
|
||||
<resData>
|
||||
<domain:infData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>domain.example</domain:name>
|
||||
<domain:roid>EXAMPLE1-REP</domain:roid>
|
||||
<domain:status s="serverUpdateProhibited"/>
|
||||
<domain:status s="serverDeleteProhibited"/>
|
||||
<domain:status s="serverTransferProhibited"/>
|
||||
<domain:registrant>jd1234</domain:registrant>
|
||||
<domain:contact type="admin">sh8013</domain:contact>
|
||||
<domain:contact type="tech">sh8013</domain:contact>
|
||||
<domain:clID>ClientX</domain:clID>
|
||||
<domain:crID>ClientY</domain:crID>
|
||||
<domain:crDate>2012-04-03T22:00:00.0Z</domain:crDate>
|
||||
<domain:upID>ClientZ</domain:upID>
|
||||
<domain:upDate>2013-10-22T14:25:57.0Z</domain:upDate>
|
||||
<domain:exDate>2014-04-03T22:00:00.0Z</domain:exDate>
|
||||
</domain:infData>
|
||||
</resData>
|
||||
<extension>
|
||||
<changePoll:changeData xmlns:changePoll="urn:ietf:params:xml:ns:changePoll-1.0" state="after">
|
||||
<changePoll:operation>update</changePoll:operation>
|
||||
<changePoll:date>2013-10-22T14:25:57.0Z</changePoll:date>
|
||||
<changePoll:svTRID>12345-XYZ</changePoll:svTRID>
|
||||
<changePoll:who>URS Admin</changePoll:who>
|
||||
<changePoll:caseId type="urs">urs123</changePoll:caseId>
|
||||
<changePoll:reason>URS Lock</changePoll:reason>
|
||||
</changePoll:changeData>
|
||||
</extension>
|
||||
<trID>
|
||||
<clTRID>cltrid:1626454866</clTRID>
|
||||
<svTRID>RO-6879-1627224678242975</svTRID>
|
||||
</trID>
|
||||
</response>
|
||||
</epp>
|
@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
An example poll <info> response with the
|
||||
<changePoll:changeData> extension for a URS lock transaction on the
|
||||
domain.example domain name, with the "before" state. The "before"
|
||||
state is reflected in the <resData> block
|
||||
-->
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<response>
|
||||
<result code="1301">
|
||||
<msg lang="en-US">Command completed successfully; ack to dequeue</msg>
|
||||
</result>
|
||||
<msgQ id="201" count="1">
|
||||
<qDate>2013-10-22T14:25:57.0Z</qDate>
|
||||
<msg>Registry initiated update of domain.</msg>
|
||||
</msgQ>
|
||||
<resData>
|
||||
<domain:infData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>domain.example</domain:name>
|
||||
<domain:roid>EXAMPLE1-REP</domain:roid>
|
||||
<domain:status s="ok"/>
|
||||
<domain:registrant>jd1234</domain:registrant>
|
||||
<domain:contact type="admin">sh8013</domain:contact>
|
||||
<domain:contact type="tech">sh8013</domain:contact>
|
||||
<domain:clID>ClientX</domain:clID>
|
||||
<domain:crID>ClientY</domain:crID>
|
||||
<domain:crDate>2012-04-03T22:00:00.0Z</domain:crDate>
|
||||
<domain:exDate>2014-04-03T22:00:00.0Z</domain:exDate>
|
||||
</domain:infData>
|
||||
</resData>
|
||||
<extension>
|
||||
<changePoll:changeData xmlns:changePoll="urn:ietf:params:xml:ns:changePoll-1.0" state="before">
|
||||
<changePoll:operation>update</changePoll:operation>
|
||||
<changePoll:date>2013-10-22T14:25:57.0Z</changePoll:date>
|
||||
<changePoll:svTRID>12345-XYZ</changePoll:svTRID>
|
||||
<changePoll:who>URS Admin</changePoll:who>
|
||||
<changePoll:caseId type="urs">urs123</changePoll:caseId>
|
||||
<changePoll:reason>URS Lock</changePoll:reason>
|
||||
</changePoll:changeData>
|
||||
</extension>
|
||||
<trID>
|
||||
<clTRID>cltrid:1626454866</clTRID>
|
||||
<svTRID>RO-6879-1627224678242975</svTRID>
|
||||
</trID>
|
||||
</response>
|
||||
</epp>
|
Loading…
Reference in New Issue
Block a user