added doc comments for all requests and responses

This commit is contained in:
Ritesh Chitlangi 2021-07-26 23:51:37 +08:00
parent 699b1e0f30
commit 70d8927989
37 changed files with 367 additions and 367 deletions

2
.gitignore vendored
View File

@ -2,5 +2,5 @@
**/target
**/certs
/config
/epp-client/misc
/epp-client/examples
Cargo.lock

View File

@ -1,328 +0,0 @@
use std::{error::Error, time::SystemTime};
use chrono::NaiveDate;
use env_logger;
use epp_client::EppClient;
use epp_client::epp::object::{StringValueTrait};
use epp_client::{epp::request, epp::xml::EppXml};
use epp_client::epp::object::data::{
PostalInfo, Address, Phone, DomainContact, ContactStatus, DomainStatus, HostObjList, HostAttrList, HostAttr, HostAddr,
Host, HostStatus
};
use epp_client::epp::*;
fn gen_client_tr_id(username: &str) -> Result<String, Box<dyn Error>> {
let timestamp = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?;
Ok(format!("{}:{}", username, timestamp.as_secs()))
}
async fn check_domains(client: &mut EppClient) {
let domains = vec!["eppdev.com", "hexonet.net"];
let domain_check = EppDomainCheck::new(domains, gen_client_tr_id("eppdev").unwrap().as_str());
client.transact::<_, EppDomainCheckResponse>(&domain_check).await.unwrap();
}
async fn check_contacts(client: &mut EppClient) {
let contacts = vec!["eppdev-contact-1", "eppdev-contact-2"];
let contact_check = EppContactCheck::new(contacts, gen_client_tr_id("eppdev").unwrap().as_str());
client.transact::<_, EppContactCheckResponse>(&contact_check).await.unwrap();
}
async fn create_contact(client: &mut EppClient) {
let street = vec!["58", "Orchid Road"];
let address = Address::new(street, "Paris", "Paris", "392374", "FR");
let postal_info = PostalInfo::new("int", "John Doe", "Acme Widgets", address);
let mut voice = Phone::new("+47.47237942");
voice.set_extension("123");
let mut fax = Phone::new("+47.86698799");
fax.set_extension("677");
let mut contact_create = EppContactCreate::new("eppdev-contact-4", "contact@eppdev.net", postal_info, voice, "eppdev-387323", gen_client_tr_id("eppdev").unwrap().as_str());
contact_create.set_fax(fax);
client.transact::<_, EppContactCreateResponse>(&contact_create).await.unwrap();
}
async fn update_contact(client: &mut EppClient) {
let contact_info = EppContactInfo::new("eppdev-contact-1", "eppdev-387323", gen_client_tr_id("eppdev").unwrap().as_str());
let contact_info_response = client.transact::<_, EppContactInfoResponse>(&contact_info).await.unwrap();
let mut contact_update = EppContactUpdate::new("eppdev-contact-1", gen_client_tr_id("eppdev").unwrap().as_str());
let contact_info_res_data = contact_info_response.data.res_data.unwrap();
contact_update.set_info("newemail@eppdev.net", contact_info_res_data.info_data.postal_info, contact_info_res_data.info_data.voice, "eppdev-387323");
let add_statuses = vec![ContactStatus { status: "clientTransferProhibited".to_string() }];
contact_update.remove_statuses(add_statuses);
client.transact::<_, EppContactUpdateResponse>(&contact_update).await.unwrap();
}
async fn query_contact(client: &mut EppClient) {
let mut contact_info = EppContactInfo::new("eppdev-contact-11", "eppdev-387323", gen_client_tr_id("eppdev").unwrap().as_str());
client.transact::<_, EppContactInfoResponse>(&contact_info).await.unwrap();
}
async fn delete_contact(client: &mut EppClient) {
let contact_delete = EppContactDelete::new("eppdev-contact-4", gen_client_tr_id("eppdev").unwrap().as_str());
client.transact::<_, EppContactDeleteResponse>(&contact_delete).await.unwrap();
}
async fn create_domain(client: &mut EppClient) {
let contacts = vec![
DomainContact {
contact_type: "admin".to_string(),
id: "eppdev-contact-2".to_string()
},
DomainContact {
contact_type: "tech".to_string(),
id: "eppdev-contact-2".to_string()
},
DomainContact {
contact_type: "billing".to_string(),
id: "eppdev-contact-2".to_string()
}
];
// let domain_create = EppDomainCreate::new_with_ns("eppdev.com", 1, vec!["ns1.test.com", "ns2.test.com"], "eppdev-contact-1", "eppdevauth123", contacts, gen_client_tr_id("eppdev").unwrap().as_str());
let domain_create = EppDomainCreate::new("eppdev-2.com", 1, "eppdev-contact-2", "epP4uthd#v", contacts, gen_client_tr_id("eppdev").unwrap().as_str());
client.transact::<_, EppDomainCreateResponse>(&domain_create).await.unwrap();
}
async fn query_domain(client: &mut EppClient) {
let domain_info = EppDomainInfo::new("eppdev-1.com", gen_client_tr_id("eppdev").unwrap().as_str());
client.transact::<_, EppDomainInfoResponse>(&domain_info).await.unwrap();
}
async fn update_domain(client: &mut EppClient) {
let mut domain_update = EppDomainUpdate::new("eppdev.com", gen_client_tr_id("eppdev").unwrap().as_str());
let remove = DomainAddRemove {
ns: None,
// ns: Some(HostAttrList {
// hosts: vec![
// HostAttr {
// name: "ns1.test.com".to_string_value(),
// addresses: Some(vec![
// HostAddr::new_v4("177.163.23.23"),
// HostAddr::new_v6("213.221.54.17"),
// ]
// )},
// HostAttr {
// name: "ns2.test.com".to_string_value(),
// addresses: None,
// },
// ]
// }),
contacts: None,
statuses: Some(vec![
DomainStatus {
status: "clientDeleteProhibited".to_string()
}
])
};
let add = DomainAddRemove {
ns: None,
contacts: Some(vec![
DomainContact {
contact_type: "billing".to_string(),
id: "eppdev-contact-2".to_string()
}
]),
statuses: None,
};
domain_update.add(add);
domain_update.remove(remove);
client.transact::<_, EppDomainUpdateResponse>(&domain_update).await.unwrap();
}
async fn delete_domain(client: &mut EppClient) {
let domain_delete = EppDomainDelete::new("eppdev-2.com", gen_client_tr_id("eppdev").unwrap().as_str());
client.transact::<_, EppDomainDeleteResponse>(&domain_delete).await.unwrap();
}
async fn renew_domain(client: &mut EppClient) {
let exp_date = NaiveDate::from_ymd(2023, 7, 23);
let renew_domain = EppDomainRenew::new("eppdev-1.com", exp_date, 1, gen_client_tr_id("eppdev").unwrap().as_str());
client.transact::<_, EppDomainRenewResponse>(&renew_domain).await.unwrap();
}
async fn request_transfer(client: &mut EppClient) {
let transfer_request = EppDomainTransferRequest::request("testing.com", 1, "epP4uthd#v", gen_client_tr_id("eppdev").unwrap().as_str());
println!("{}\n\n", transfer_request.serialize().unwrap());
}
async fn approve_transfer(client: &mut EppClient) {
let transfer_approve = EppDomainTransferRequest::approve("testing.com", gen_client_tr_id("eppdev").unwrap().as_str());
println!("{}\n\n", transfer_approve.serialize().unwrap());
}
async fn reject_transfer(client: &mut EppClient) {
let transfer_reject = EppDomainTransferRequest::reject("testing.com", gen_client_tr_id("eppdev").unwrap().as_str());
println!("{}\n\n", transfer_reject.serialize().unwrap());
}
async fn cancel_transfer(client: &mut EppClient) {
let transfer_cancel = EppDomainTransferRequest::cancel("testing.com", gen_client_tr_id("eppdev").unwrap().as_str());
println!("{}\n\n", transfer_cancel.serialize().unwrap());
}
async fn query_transfer(client: &mut EppClient) {
let transfer_query = EppDomainTransferRequest::query("testing.com", "epP4uthd#v", gen_client_tr_id("eppdev").unwrap().as_str());
println!("{}\n\n", transfer_query.serialize().unwrap());
}
async fn check_hosts(client: &mut EppClient) {
let hosts_check = EppHostCheck::new(vec!["host1.eppdev-1.com", "ns1.testing.com"], gen_client_tr_id("eppdev").unwrap().as_str());
client.transact::<_, EppHostCheckResponse>(&hosts_check).await.unwrap();
}
async fn create_host(client: &mut EppClient) {
let host = Host {
name: "host2.eppdev-1.com".to_string_value(),
addresses: Some(vec![
HostAddr::new("v4", "29.245.122.14"),
HostAddr::new("v6", "2404:6800:4001:801::200e"),
])
};
let host_create = EppHostCreate::new(host, gen_client_tr_id("eppdev").unwrap().as_str());
client.transact::<_, EppHostCreateResponse>(&host_create).await.unwrap();
}
async fn query_host(client: &mut EppClient) {
let host_info = EppHostInfo::new("host2.eppdev-1.com", gen_client_tr_id("eppdev").unwrap().as_str());
client.transact::<_, EppHostInfoResponse>(&host_info).await.unwrap();
}
async fn update_host(client: &mut EppClient) {
let addr = vec![
HostAddr::new("v6", "2404:6800:4001:801::200e"),
];
let add = HostAddRemove {
addresses: Some(addr),
statuses: None,
};
let remove = HostAddRemove {
addresses: None,
statuses: Some(vec![
HostStatus {
status: "clientDeleteProhibited".to_string()
}
]),
};
let mut host_update = EppHostUpdate::new("host1.eppdev-1.com", gen_client_tr_id("eppdev").unwrap().as_str());
host_update.add(add);
// host_update.remove(remove);
host_update.info(HostChangeInfo { name: "host2.eppdev-1.com".to_string_value() });
client.transact::<_, EppHostUpdateResponse>(&host_update).await.unwrap();
}
async fn delete_host(client: &mut EppClient) {
let host_delete = EppHostDelete::new("host2.eppdev-1.com", gen_client_tr_id("eppdev").unwrap().as_str());
client.transact::<_, EppHostDeleteResponse>(&host_delete).await.unwrap();
}
async fn poll_message(client: &mut EppClient) {
let message_poll = EppMessagePoll::new(gen_client_tr_id("eppdev").unwrap().as_str());
client.transact::<_, EppMessagePollResponse>(&message_poll).await.unwrap();
}
async fn ack_message(client: &mut EppClient) {
let message_ack = EppMessageAck::new(12345, gen_client_tr_id("eppdev").unwrap().as_str());
println!("{}", message_ack.serialize().unwrap());
// client.transact::<_, EppMessageAckResponse>(&message_ack).await.unwrap();
}
async fn hello(client: &mut EppClient) {
let greeting = client.hello().await.unwrap();
println!("{:?}", greeting);
}
#[tokio::main]
async fn main() {
env_logger::init();
let mut client = match EppClient::new("verisign").await {
Ok(client) => client,
Err(e) => panic!("Error: {}", e)
};
// client.set_client_tr_id_fn(gen_client_tr_id);
// hello(&mut client).await;
// check_domains(&mut client).await;
// check_contacts(&mut client).await;
// create_contact(&mut client).await;
// query_contact(&mut client).await;
// update_contact(&mut client).await;
// delete_contact(&mut client).await;
// create_domain(&mut client).await;
// query_domain(&mut client).await;
// update_domain(&mut client).await;
// delete_domain(&mut client).await;
// renew_domain(&mut client).await;
// request_transfer(&mut client).await;
// query_transfer(&mut client).await;
// approve_transfer(&mut client).await;
// reject_transfer(&mut client).await;
// cancel_transfer(&mut client).await;
// check_hosts(&mut client).await;
// create_host(&mut client).await;
// query_host(&mut client).await;
// update_host(&mut client).await;
// delete_host(&mut client).await;
poll_message(&mut client).await;
// ack_message(&mut client).await;
}

View File

@ -43,6 +43,7 @@ impl EppConnection {
})
}
/// Writes to the socket
async fn write(&mut self, buf: &Vec<u8>) -> Result<(), Box<dyn Error>> {
let wrote = self.stream.writer.write(buf).await?;
@ -51,6 +52,7 @@ impl EppConnection {
Ok(())
}
/// Constructs an EPP XML request in the required form and sends it to the server
async fn send_epp_request(&mut self, content: &str) -> Result<(), Box<dyn Error>> {
let len = content.len();
@ -66,6 +68,7 @@ impl EppConnection {
self.write(&buf).await
}
/// Reads response from the socket
async fn read_epp_response(&mut self) -> Result<Vec<u8>, Box<dyn Error>> {
let mut buf = [0u8; 4];
self.stream.reader.read_exact(&mut buf).await?;
@ -100,6 +103,7 @@ impl EppConnection {
Ok(data)
}
/// Receives response from the socket and converts it into an EPP XML string
async fn get_epp_response(&mut self) -> Result<String, Box<dyn Error>> {
let contents = self.read_epp_response().await?;
@ -108,7 +112,7 @@ impl EppConnection {
Ok(response)
}
/// Send an EPP XML request to the registry and return the response
/// Sends an EPP XML request to the registry and return the response
/// receieved to the request
pub async fn transact(&mut self, content: &str) -> Result<String, Box<dyn Error>> {
debug!("{}: request: {}", self.registry, content);
@ -120,6 +124,7 @@ impl EppConnection {
Ok(response)
}
/// Closes the socket
async fn close(&mut self) -> Result<(), Box<dyn Error>> {
info!("{}: Closing connection", self.registry);
@ -134,7 +139,7 @@ impl Drop for EppConnection {
}
}
/// Establish a TLS connection to a registry and return a ConnectionStream instance containing the
/// Establishes a TLS connection to a registry and returns a ConnectionStream instance containing the
/// socket stream to read/write to the connection
pub async fn epp_connect(registry_creds: &EppClientConnection) -> Result<ConnectionStream, error::Error> {
let (host, port) = registry_creds.connection_details();

View File

@ -1,3 +1,5 @@
//! Types for EPP requests and responses
pub mod object;
pub mod request;
pub mod response;

View File

@ -8,13 +8,6 @@ pub type DomainStatus = ContactStatus;
/// The <status> attribute on EPP XML for host transactions
pub type HostStatus = ContactStatus;
/// The <hostObj> or <hostAttr> types under an <ns> tag on domain transactions
#[derive(Serialize, Deserialize, Debug)]
pub enum DomainNsList {
HostAttrList(HostAttrList),
HostObjList(HostObjList),
}
/// The <hostAddr> types domain or host transactions
#[derive(Serialize, Deserialize, Debug)]
pub struct HostAddr {

View File

@ -1,3 +1,5 @@
//! Types for EPP requests
pub mod contact;
pub mod domain;
pub mod host;
@ -13,19 +15,26 @@ use crate::epp::object::{
use crate::epp::xml::{EPP_CONTACT_XMLNS, EPP_DOMAIN_XMLNS, EPP_HOST_XMLNS, EPP_LANG, EPP_VERSION};
use epp_client_macros::*;
/// The EPP Hello request
pub type EppHello = EppObject<Hello>;
/// The EPP Login Request
pub type EppLogin = EppObject<Command<Login>>;
/// The EPP Logout request
pub type EppLogout = EppObject<Command<Logout>>;
#[derive(Deserialize, Debug, PartialEq, ElementName)]
#[element_name(name = "command")]
/// Type corresponding to the <command> tag in an EPP XML request
pub struct Command<T: ElementName> {
/// The instance that will be used to populate the <command> tag
pub command: T,
/// The client TRID
#[serde(rename = "clTRID")]
pub client_tr_id: StringValue,
}
impl<T: ElementName + Serialize> Serialize for Command<T> {
/// Serializes the generic type T to the proper XML tag (set by the `#[element_name(name = <tagname>)]` attribute) for the request
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
@ -38,6 +47,7 @@ impl<T: ElementName + Serialize> Serialize for Command<T> {
}
}
/// Basic client TRID generation function. Mainly used for testing. Users of the library should use their own clTRID generation function.
pub fn generate_client_tr_id(username: &str) -> Result<String, Box<dyn Error>> {
let timestamp = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?;
Ok(format!("{}:{}", username, timestamp.as_secs()))
@ -45,9 +55,11 @@ pub fn generate_client_tr_id(username: &str) -> Result<String, Box<dyn Error>> {
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
#[element_name(name = "hello")]
/// Type corresponding to the <hello> tag in an EPP XML hello request
pub struct Hello;
impl EppHello {
/// Creates a new Epp Hello request
pub fn new() -> EppHello {
EppObject::build(Hello {})
}
@ -55,17 +67,23 @@ impl EppHello {
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
#[element_name(name = "login")]
/// Type corresponding to the <login> tag in an EPP XML login request
pub struct Login {
/// The username to use for the login
#[serde(rename(serialize = "clID", deserialize = "clID"))]
username: StringValue,
/// The password to use for the login
#[serde(rename = "pw", default)]
password: StringValue,
/// Data under the <options> tag
options: Options,
/// Data under the <svcs> tag
#[serde(rename = "svcs")]
services: Services,
}
impl EppLogin {
/// Creates a new EPP Login request
pub fn new(
username: &str,
password: &str,
@ -104,20 +122,24 @@ impl EppLogin {
})
}
pub fn set_options(&mut self, options: Options) {
/// Sets the <options> tag data
pub fn options(&mut self, options: Options) {
self.data.command.options = options;
}
pub fn set_services(&mut self, services: Services) {
/// Sets the <svcs> tag data
pub fn services(&mut self, services: Services) {
self.data.command.services = services;
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
#[element_name(name = "logout")]
/// Type corresponding to the <logout> tag in an EPP XML logout request
pub struct Logout;
impl EppLogout {
/// Creates a new EPP Logout request
pub fn new(client_tr_id: &str) -> EppLogout {
EppObject::build(Command::<Logout> {
command: Logout,

View File

@ -1,3 +1,5 @@
//! Types for EPP responses
pub mod contact;
pub mod domain;
pub mod host;
@ -10,18 +12,25 @@ use crate::epp::object::{
ElementName, EppObject, Options, ServiceExtension, Services, StringValue,
};
/// The EPP Greeting that is received on a successful connection and in response to an EPP hello
pub type EppGreeting = EppObject<Greeting>;
/// A generic EPP Response to an EPP command with a result section, a status code and a message
pub type EppCommandResponse = EppObject<CommandResponseStatus>;
/// An alias of `EppCommandResponse` indicating an EPP Error
pub type EppCommandResponseError = EppCommandResponse;
/// An alias of `EppCommandResponse` received in response to a successful login request
pub type EppLoginResponse = EppCommandResponse;
/// An alias of `EppCommandResponse` received in response to a successful logout request
pub type EppLogoutResponse = EppCommandResponse;
/// Type for data within the <svcMenu> section of an EPP greeting
#[derive(Serialize, Debug, PartialEq)]
pub struct ServiceMenu {
pub options: Options,
pub services: Services,
}
/// Simplified service menu type for deserialization to `ServiceMenu` type from EPP greeting XML
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct FlattenedServiceMenu {
pub version: StringValue,
@ -33,6 +42,7 @@ struct FlattenedServiceMenu {
}
impl<'de> Deserialize<'de> for ServiceMenu {
/// Deserializes the <svcMenu> data to the `ServiceMenu` type
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
@ -54,111 +64,158 @@ impl<'de> Deserialize<'de> for ServiceMenu {
}
}
/// Type corresponding to <all> in the EPP greeting XML (pending more compliant implementation)
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct All;
/// Type corresponding to <access> in the EPP greeting XML (pending more compliant implementation)
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct Access {
/// Data for the <all> tag
pub all: All,
}
/// Type corresponding to <admin> in the EPP greeting XML (pending more compliant implementation)
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct Admin;
/// Type corresponding to <prov> in the EPP greeting XML (pending more compliant implementation)
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct Prov;
/// Type corresponding to <purpose> in the EPP greeting XML (pending more compliant implementation)
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct Purpose {
/// Data for the <admin> tag
pub admin: Admin,
/// Data for the <prov> tag
pub prov: Prov,
}
/// Type corresponding to <ours> in the EPP greeting XML (pending more compliant implementation)
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct Ours;
/// Type corresponding to <public> in the EPP greeting XML (pending more compliant implementation)
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct Public;
/// Type corresponding to <recipeint> in the EPP greeting XML (pending more compliant implementation)
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct Recipient {
/// Data for the <ours> tag
pub ours: Ours,
/// Data for the <public> tag
pub public: Public,
}
/// Type corresponding to <stated> in the EPP greeting XML (pending more compliant implementation)
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct Stated;
/// Type corresponding to <retention> in the EPP greeting XML (pending more compliant implementation)
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct Retention {
/// Data for the <stated> tag
pub stated: Stated,
}
/// Type corresponding to <statement> in the EPP greeting XML (pending more compliant implementation)
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct Statement {
/// Data for the <purpose> tag
pub purpose: Purpose,
/// Data for the <recipient> tag
pub recipient: Recipient,
/// Data for the <retention> tag
pub retention: Retention,
}
/// Type corresponding to <dcp> in the EPP greeting XML (pending more compliant implementation)
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct Dcp {
/// Data for the <access> tag
pub access: Access,
/// Data for the <statement> tag
pub statement: Statement,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
#[serde(rename_all = "lowercase")]
#[element_name(name = "greeting")]
/// Type corresponding to the <greeting> tag in the EPP greeting XML
pub struct Greeting {
/// The service ID
#[serde(rename = "svID")]
pub service_id: String,
/// The date from the EPP server
#[serde(rename = "svDate")]
pub service_date: String,
/// Data under the <svcMenu> element
#[serde(rename = "svcMenu")]
pub svc_menu: ServiceMenu,
/// Data under the <dcp> element
pub dcp: Dcp,
}
/// Type corresponding to the <undef> tag an EPP response XML
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct Undef;
/// Type corresponding to the <value> tag under <extValue> in an EPP response XML
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct ResultValue {
/// The XML namespace for the <value> tag
#[serde(rename = "xmlns:epp")]
xmlns: String,
/// The <undef> element
pub undef: Undef,
}
/// Type corresponding to the <extValue> tag in an EPP response XML
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct ExtValue {
/// Data under the <value> tag
pub value: ResultValue,
/// Data under the <reason> tag
pub reason: StringValue,
}
/// Type corresponding to the <result> tag in an EPP response XML
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct EppResult {
/// The result code
pub code: u16,
/// The result message
#[serde(rename = "msg")]
pub message: StringValue,
/// Data under the <extValue> tag
#[serde(rename = "extValue")]
pub ext_value: Option<ExtValue>,
}
/// Type corresponding to the <trID> tag in an EPP response XML
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct ResponseTRID {
/// The client TRID
#[serde(rename = "clTRID")]
pub client_tr_id: Option<StringValue>,
/// The server TRID
#[serde(rename = "svTRID")]
pub server_tr_id: StringValue,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
/// Type corresponding to the <msgQ> tag in an EPP response XML
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct MessageQueue {
/// The message count
pub count: u32,
/// The message ID
pub id: String,
/// The message date
#[serde(rename = "qDate")]
pub date: Option<StringValue>,
/// The message text
#[serde(rename = "msg")]
pub message: Option<StringValue>,
}
@ -166,31 +223,42 @@ pub struct MessageQueue {
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
#[serde(rename_all = "lowercase")]
#[element_name(name = "response")]
/// Type corresponding to the <response> tag in an EPP response XML
pub struct CommandResponse<T> {
/// Data under the <result> tag
pub result: EppResult,
/// Data under the <msgQ> tag
#[serde(rename = "msgQ")]
pub message_queue: Option<MessageQueue>,
#[serde(rename = "resData")]
/// Data under the <resData> tag
pub res_data: Option<T>,
/// Data under the <trID> tag
#[serde(rename = "trID")]
pub tr_ids: ResponseTRID,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
#[element_name(name = "response")]
/// Type corresponding to the <response> tag in an EPP response XML
/// without <msgQ> or <resData> sections. Generally used for error handling
pub struct CommandResponseStatus {
/// Data under the <result> tag
pub result: EppResult,
#[serde(rename = "trID")]
/// Data under the <trID> tag
pub tr_ids: ResponseTRID,
}
impl<T> CommandResponse<T> {
/// Returns the data under the corresponding <resData> from the EPP XML
pub fn res_data(&self) -> Option<&T> {
match &self.res_data {
Some(res_data) => Some(&res_data),
None => None,
}
}
/// Returns the data under the corresponding <msgQ> from the EPP XML
pub fn message_queue(&self) -> Option<&MessageQueue> {
match &self.message_queue {
Some(queue) => Some(&queue),

View File

@ -1,3 +1,5 @@
//! Module containing types for EPP contact transactions
pub mod check;
pub mod create;
pub mod delete;

View File

@ -1,37 +1,52 @@
//! Types for EPP contact check response
use serde::{Deserialize, Serialize};
use crate::epp::object::{EppObject, StringValue};
use crate::epp::response::CommandResponse;
/// Type that represents the <epp> tag for the EPP XML contact check response
pub type EppContactCheckResponse = EppObject<CommandResponse<ContactCheckResult>>;
/// Type that represents the <id> tag for contact check response
#[derive(Serialize, Deserialize, Debug)]
pub struct ContactCheck {
/// The text of the <id> tag
#[serde(rename = "$value")]
pub id: StringValue,
/// The avail attr on the <id> tag
#[serde(rename = "avail")]
pub available: u16,
}
/// Type that represents the <cd> tag for contact check response
#[derive(Serialize, Deserialize, Debug)]
pub struct ContactCheckDataItem {
/// Data under the <id> tag
#[serde(rename = "id")]
pub contact: ContactCheck,
/// The reason for (un)availability
pub reason: Option<StringValue>,
}
/// Type that represents the <chkData> tag for contact check response
#[derive(Serialize, Deserialize, Debug)]
pub struct ContactCheckData {
/// XML namespace for contact response data
#[serde(rename = "xmlns:contact")]
xmlns: String,
/// XML schema location for contact response data
#[serde(rename = "xsi:schemaLocation")]
schema_location: String,
/// Data under the <cd> tag
#[serde(rename = "cd")]
pub contact_list: Vec<ContactCheckDataItem>,
}
/// Type that represents the <resData> tag for contact check response
#[derive(Serialize, Deserialize, Debug)]
pub struct ContactCheckResult {
/// Data under the <chkData> tag
#[serde(rename = "chkData")]
pub check_data: ContactCheckData,
}

View File

@ -1,23 +1,33 @@
//! Types for EPP contact create response
use serde::{Deserialize, Serialize};
use crate::epp::object::{EppObject, StringValue};
use crate::epp::response::CommandResponse;
/// Type that represents the <epp> tag for the EPP XML contact create response
pub type EppContactCreateResponse = EppObject<CommandResponse<ContactCreateResult>>;
/// Type that represents the <creData> tag for contact create response
#[derive(Serialize, Deserialize, Debug)]
pub struct ContactCreateData {
/// XML namespace for contact response data
#[serde(rename = "xmlns:contact")]
xmlns: String,
/// XML schema location for contact response data
#[serde(rename = "xsi:schemaLocation")]
schema_location: String,
/// The contact id
pub id: StringValue,
#[serde(rename = "crDate")]
/// The contact creation date
pub created_at: StringValue,
}
/// Type that represents the <resData> tag for contact create response
#[derive(Serialize, Deserialize, Debug)]
pub struct ContactCreateResult {
/// Data under the <creData> tag
#[serde(rename = "creData")]
pub create_data: ContactCreateData,
}

View File

@ -1,3 +1,6 @@
//! Types for EPP contact delete response
use crate::epp::response::EppCommandResponse;
/// Type that represents the <epp> tag for the EPP XML contact delete response
pub type EppContactDeleteResponse = EppCommandResponse;

View File

@ -1,44 +1,66 @@
//! Types for EPP contact info response
use serde::{Deserialize, Serialize};
use crate::epp::object::data::{AuthInfo, ContactStatus, Phone, PostalInfo};
use crate::epp::object::{EppObject, StringValue};
use crate::epp::response::CommandResponse;
/// Type that represents the <epp> tag for the EPP XML contact info response
pub type EppContactInfoResponse = EppObject<CommandResponse<ContactInfoResult>>;
/// Type that represents the <infData> tag for contact check response
#[derive(Serialize, Deserialize, Debug)]
pub struct ContactInfoData {
/// XML namespace for contact response data
#[serde(rename = "xmlns:contact")]
xmlns: String,
/// XML schema location for contact response data
#[serde(rename = "xsi:schemaLocation")]
schema_location: String,
/// The contact id
pub id: StringValue,
/// The contact ROID
pub roid: StringValue,
/// The list of contact statuses
#[serde(rename = "status")]
pub statuses: Vec<ContactStatus>,
/// The postal info for the contact
#[serde(rename = "postalInfo")]
pub postal_info: PostalInfo,
/// The voice data for the contact
pub voice: Phone,
/// The fax data for the contact
pub fax: Option<Phone>,
/// The email for the contact
pub email: StringValue,
/// The epp user to whom the contact belongs
#[serde(rename = "clID")]
pub client_id: StringValue,
/// The epp user who created the contact
#[serde(rename = "crID")]
pub creator_id: StringValue,
/// The creation date
#[serde(rename = "crDate")]
pub created_at: StringValue,
/// The epp user who last updated the contact
#[serde(rename = "upID")]
pub updater_id: Option<StringValue>,
/// The last update date
#[serde(rename = "upDate")]
pub updated_at: Option<StringValue>,
/// The contact transfer date
#[serde(rename = "trDate")]
pub transferred_at: Option<StringValue>,
/// The contact auth info
#[serde(rename = "authInfo")]
pub auth_info: Option<AuthInfo>,
}
/// Type that represents the <resData> tag for contact info response
#[derive(Serialize, Deserialize, Debug)]
pub struct ContactInfoResult {
/// Data under the <infData> tag
#[serde(rename = "infData")]
pub info_data: ContactInfoData,
}

View File

@ -1,3 +1,6 @@
//! Types for EPP contact update response
use crate::epp::response::EppCommandResponse;
/// Type that represents the <epp> tag for the EPP XML contact update response
pub type EppContactUpdateResponse = EppCommandResponse;

View File

@ -1,3 +1,5 @@
//! Module containing types for EPP domain transactions
pub mod check;
pub mod create;
pub mod delete;

View File

@ -1,37 +1,52 @@
//! Types for EPP domain check response
use serde::{Deserialize, Serialize};
use crate::epp::object::{EppObject, StringValue};
use crate::epp::response::CommandResponse;
/// Type that represents the <epp> tag for the EPP XML domain check response
pub type EppDomainCheckResponse = EppObject<CommandResponse<DomainCheckResult>>;
/// Type that represents the <name> tag for domain check response
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainCheck {
/// The domain name
#[serde(rename = "$value")]
pub name: StringValue,
/// The domain (un)availability
#[serde(rename = "avail")]
pub available: u16,
}
/// Type that represents the <cd> tag for domain check response
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainCheckDataItem {
/// Data under the <name> tag
#[serde(rename = "name")]
pub domain: DomainCheck,
/// The reason for (un)availability
pub reason: Option<StringValue>,
}
/// Type that represents the <chkData> tag for domain check response
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainCheckData {
/// XML namespace for domain response data
#[serde(rename = "xmlns:domain")]
xmlns: String,
/// XML schema location for domain response data
#[serde(rename = "xsi:schemaLocation")]
schema_location: String,
/// Data under the <cd> tag
#[serde(rename = "cd")]
pub domain_list: Vec<DomainCheckDataItem>,
}
/// Type that represents the <resData> tag for domain check response
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainCheckResult {
/// Data under the <chkData> tag
#[serde(rename = "chkData")]
pub check_data: DomainCheckData,
}

View File

@ -1,25 +1,36 @@
//! Types for EPP domain create response
use serde::{Deserialize, Serialize};
use crate::epp::object::{EppObject, StringValue};
use crate::epp::response::CommandResponse;
/// Type that represents the <epp> tag for the EPP XML domain create response
pub type EppDomainCreateResponse = EppObject<CommandResponse<DomainCreateResult>>;
/// Type that represents the <chkData> tag for domain create response
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainCreateData {
/// XML namespace for domain response data
#[serde(rename = "xmlns:domain")]
xmlns: String,
/// XML schema location for domain response data
#[serde(rename = "xsi:schemaLocation")]
schema_location: String,
/// The domain name
pub name: StringValue,
/// The creation date
#[serde(rename = "crDate")]
pub created_at: StringValue,
/// The expiry date
#[serde(rename = "exDate")]
pub expiry_date: StringValue,
pub expiring_at: StringValue,
}
/// Type that represents the <resData> tag for domain create response
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainCreateResult {
/// Data under the <chkData> tag
#[serde(rename = "creData")]
pub create_data: DomainCreateData,
}

View File

@ -1,3 +1,6 @@
//! Types for EPP domain delete response
use crate::epp::response::EppCommandResponse;
/// Type that represents the <epp> tag for the EPP XML domain delete response
pub type EppDomainDeleteResponse = EppCommandResponse;

View File

@ -1,58 +1,76 @@
//! Types for EPP domain info response
use serde::{Deserialize, Serialize};
use crate::epp::object::data::{AuthInfo, DomainContact, DomainNsList, DomainStatus};
use crate::epp::object::data::{AuthInfo, DomainContact, DomainStatus, HostAttr};
use crate::epp::object::{EppObject, StringValue};
use crate::epp::response::CommandResponse;
/// Type that represents the <epp> tag for the EPP XML domain info response
pub type EppDomainInfoResponse = EppObject<CommandResponse<DomainInfoResult>>;
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainCheck {
#[serde(rename = "$value")]
pub name: StringValue,
#[serde(rename = "avail")]
pub available: u16,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainCheckDataItem {
pub name: DomainCheck,
pub reason: Option<StringValue>,
pub struct DomainNsList {
#[serde(rename = "hostObj")]
pub host_obj: Option<Vec<StringValue>>,
#[serde(rename = "hostAttr")]
pub host_attr: Option<Vec<HostAttr>>,
}
/// Type that represents the <infData> tag for domain info response
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainInfoData {
/// XML namespace for domain response data
#[serde(rename = "xmlns:domain")]
xmlns: String,
/// XML schema location for domain response data
#[serde(rename = "xsi:schemaLocation")]
schema_location: String,
/// The domain name
pub name: StringValue,
/// The domain ROID
pub roid: StringValue,
/// The list of domain statuses
#[serde(rename = "status")]
pub statuses: Vec<DomainStatus>,
/// The domain registrant
pub registrant: StringValue,
/// The list of domain contacts
#[serde(rename = "contact")]
pub contacts: Vec<DomainContact>,
/// The list of domain nameservers
#[serde(rename = "ns")]
pub ns: Option<DomainNsList>,
pub host: Option<Vec<StringValue>>,
/// The list of domain hosts
#[serde(rename = "host")]
pub hosts: Option<Vec<StringValue>>,
/// The epp user who owns the domain
#[serde(rename = "clID")]
pub client_id: StringValue,
/// The epp user who created the domain
#[serde(rename = "crID")]
pub creator_id: StringValue,
/// The domain creation date
#[serde(rename = "crDate")]
pub created_at: StringValue,
/// The epp user who last updated the domain
#[serde(rename = "upID")]
pub updater_id: StringValue,
/// The domain last updated date
#[serde(rename = "upDate")]
pub updated_at: StringValue,
/// The domain expiry date
#[serde(rename = "exDate")]
pub expiry_date: StringValue,
pub expiring_at: StringValue,
/// The domain transfer date
#[serde(rename = "trDate")]
pub transferred_at: Option<StringValue>,
/// The domain auth info
#[serde(rename = "authInfo")]
pub auth_info: Option<AuthInfo>,
}
/// Type that represents the <resData> tag for domain info response
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainInfoResult {
#[serde(rename = "infData")]

View File

@ -1,23 +1,32 @@
//! Types for EPP domain renew response
use serde::{Deserialize, Serialize};
use crate::epp::object::{EppObject, StringValue};
use crate::epp::response::CommandResponse;
/// Type that represents the <epp> tag for the EPP XML domain renew response
pub type EppDomainRenewResponse = EppObject<CommandResponse<DomainRenewResult>>;
/// Type that represents the <renData> tag for domain renew response
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainRenewData {
/// XML namespace for domain response data
#[serde(rename = "xmlns:domain")]
xmlns: String,
/// XML schema location for domain response data
#[serde(rename = "xsi:schemaLocation")]
schema_location: String,
/// The name of the domain
pub name: StringValue,
/// The new expiry date after renewal
#[serde(rename = "exDate")]
pub expiry_date: StringValue,
pub expiring_at: StringValue,
}
/// Type that represents the <resData> tag for domain renew response
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainRenewResult {
/// Data under the <renData> tag
#[serde(rename = "renData")]
pub renew_data: DomainRenewData,
}

View File

@ -1,38 +1,56 @@
//! Types for EPP domain transfer response
use serde::{Deserialize, Serialize};
use crate::epp::object::{EppObject, StringValue};
use crate::epp::response::CommandResponse;
use crate::epp::response::EppCommandResponse;
/// Type that represents the <epp> tag for the EPP XML domain transfer request response
pub type EppDomainTransferRequestResponse = EppObject<CommandResponse<DomainTransferResult>>;
/// Type that represents the <epp> tag for the EPP XML domain transfer approval response
pub type EppDomainTransferApproveResponse = EppCommandResponse;
/// Type that represents the <epp> tag for the EPP XML domain transfer rejection response
pub type EppDomainTransferRejectResponse = EppCommandResponse;
/// Type that represents the <epp> tag for the EPP XML domain transfer cancellation response
pub type EppDomainTransferCancelResponse = EppCommandResponse;
/// Type that represents the <epp> tag for the EPP XML domain transfer query response
pub type EppDomainTransferQueryResponse = EppObject<CommandResponse<DomainTransferResult>>;
/// Type that represents the <trnData> tag for domain transfer response
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainTransferData {
/// XML namespace for domain response data
#[serde(rename = "xmlns:domain")]
xmlns: String,
/// XML schema location for domain response data
#[serde(rename = "xsi:schemaLocation")]
schema_location: String,
/// The domain name
pub name: StringValue,
/// The domain transfer status
#[serde(rename = "trStatus")]
pub transfer_status: StringValue,
/// The epp user who requested the transfer
#[serde(rename = "reID")]
pub requester_id: StringValue,
/// The transfer rquest date
#[serde(rename = "reDate")]
pub requested_at: StringValue,
/// The epp user who should acknowledge the transfer request
#[serde(rename = "acID")]
pub ack_id: StringValue,
/// THe date by which the acknowledgment should be made
#[serde(rename = "acDate")]
pub ack_by: StringValue,
/// The domain expiry date
#[serde(rename = "exDate")]
pub expiry_date: StringValue,
pub expiring_at: StringValue,
}
/// Type that represents the <resData> tag for domain transfer response
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainTransferResult {
/// Data under the <trnData> tag
#[serde(rename = "trnData")]
pub transfer_data: DomainTransferData,
}

View File

@ -1,3 +1,6 @@
//! Types for EPP domain update response
use crate::epp::response::EppCommandResponse;
/// Type that represents the <epp> tag for the EPP XML domain update response
pub type EppDomainUpdateResponse = EppCommandResponse;

View File

@ -1,3 +1,5 @@
//! Module containing types for EPP host transactions
pub mod check;
pub mod create;
pub mod delete;

View File

@ -1,35 +1,52 @@
//! Types for EPP host check response
use serde::{Deserialize, Serialize};
use crate::epp::object::{EppObject, StringValue};
use crate::epp::response::CommandResponse;
/// Type that represents the <epp> tag for the EPP XML host check response
pub type EppHostCheckResponse = EppObject<CommandResponse<HostCheckResult>>;
/// Type that represents the <name> tag for host check response
#[derive(Serialize, Deserialize, Debug)]
pub struct HostCheck {
/// The host name
#[serde(rename = "$value")]
pub name: StringValue,
/// The host (un)availability
#[serde(rename = "avail")]
pub available: u16,
}
/// Type that represents the <cd> tag for host check response
#[derive(Serialize, Deserialize, Debug)]
pub struct HostCheckDataItem {
/// Data under the <name> tag
#[serde(rename = "name")]
pub host: HostCheck,
/// The reason for (un)availability
pub reason: Option<StringValue>,
}
/// Type that represents the <chkData> tag for host check response
#[derive(Serialize, Deserialize, Debug)]
pub struct HostCheckData {
/// XML namespace for host response data
#[serde(rename = "xmlns:host")]
xmlns: String,
/// XML schema location for host response data
#[serde(rename = "xsi:schemaLocation")]
schema_location: String,
/// Data under the <cd> tag
#[serde(rename = "cd")]
pub host_list: Vec<HostCheckDataItem>,
}
/// Type that represents the <resData> tag for host check response
#[derive(Serialize, Deserialize, Debug)]
pub struct HostCheckResult {
/// Data under the <chkData> tag
#[serde(rename = "chkData")]
pub check_data: HostCheckData,
}

View File

@ -1,21 +1,33 @@
//! Types for EPP host create response
use serde::{Deserialize, Serialize};
use crate::epp::object::{EppObject, StringValue};
use crate::epp::response::CommandResponse;
/// Type that represents the <epp> tag for the EPP XML host create response
pub type EppHostCreateResponse = EppObject<CommandResponse<HostCreateResult>>;
/// Type that represents the <creData> tag for host create response
#[derive(Serialize, Deserialize, Debug)]
pub struct HostCreateData {
/// XML namespace for host response data
#[serde(rename = "xmlns:host")]
xmlns: String,
/// XML schema location for host response data
#[serde(rename = "xsi:schemaLocation")]
schema_location: String,
/// The host name
pub name: StringValue,
/// The host creation date
#[serde(rename = "crDate")]
pub created_at: StringValue,
}
/// Type that represents the <resData> tag for host check response
#[derive(Serialize, Deserialize, Debug)]
pub struct HostCreateResult {
/// Data under the <creData> tag
#[serde(rename = "creData")]
pub create_data: HostCreateData,
}

View File

@ -1,3 +1,6 @@
//! Types for EPP host delete response
use crate::epp::response::EppCommandResponse;
/// Type that represents the <epp> tag for the EPP XML host delete response
pub type EppHostDeleteResponse = EppCommandResponse;

View File

@ -1,37 +1,57 @@
//! Types for EPP host info response
use serde::{Deserialize, Serialize};
use crate::epp::object::data::{HostAddr, HostStatus};
use crate::epp::object::{EppObject, StringValue};
use crate::epp::response::CommandResponse;
/// Type that represents the <epp> tag for the EPP XML host info response
pub type EppHostInfoResponse = EppObject<CommandResponse<HostInfoResult>>;
/// Type that represents the <infData> tag for host info response
#[derive(Serialize, Deserialize, Debug)]
pub struct HostInfoData {
/// XML namespace for host response data
#[serde(rename = "xmlns:host")]
xmlns: String,
/// XML schema location for host response data
#[serde(rename = "xsi:schemaLocation")]
schema_location: String,
/// The host name
pub name: StringValue,
/// The host ROID
pub roid: StringValue,
/// The list of host statuses
#[serde(rename = "status")]
pub statuses: Vec<HostStatus>,
/// The list of host IP addresses
#[serde(rename = "addr")]
pub addresses: Vec<HostAddr>,
/// The epp user to whom the host belongs
#[serde(rename = "clID")]
pub client_id: StringValue,
/// THe epp user that created the host
#[serde(rename = "crID")]
pub creator_id: StringValue,
/// The host creation date
#[serde(rename = "crDate")]
pub created_at: StringValue,
/// The epp user that last updated the host
#[serde(rename = "upID")]
pub updater_id: Option<StringValue>,
/// The host last update date
#[serde(rename = "upDate")]
pub updated_at: Option<StringValue>,
/// The host transfer date
#[serde(rename = "trDate")]
pub transferred_at: Option<StringValue>,
}
/// Type that represents the <resData> tag for host info response
#[derive(Serialize, Deserialize, Debug)]
pub struct HostInfoResult {
/// Data under the <infData> tag
#[serde(rename = "infData")]
pub info_data: HostInfoData,
}

View File

@ -1,3 +1,6 @@
//! Types for EPP host check response
use crate::epp::response::EppCommandResponse;
/// Type that represents the <epp> tag for the EPP XML host update response
pub type EppHostUpdateResponse = EppCommandResponse;

View File

@ -1,2 +1,4 @@
//! Module containing types for EPP message transactions
pub mod ack;
pub mod poll;

View File

@ -1,4 +1,7 @@
//! Types for EPP message ack response
use crate::epp::object::EppObject;
use crate::epp::response::CommandResponse;
/// Type that represents the <epp> tag for the EPP XML message ack response
pub type EppMessageAckResponse = EppObject<CommandResponse<String>>;

View File

@ -1,30 +1,44 @@
//! Types for EPP message poll response
use crate::epp::object::{EppObject, StringValue};
use crate::epp::response::CommandResponse;
use serde::{Deserialize, Serialize};
/// Type that represents the <epp> tag for the EPP XML message poll response
pub type EppMessagePollResponse = EppObject<CommandResponse<MessagePollResult>>;
/// Type that represents the <trnData> tag for message poll response
#[derive(Serialize, Deserialize, Debug)]
pub struct MessageDomainTransferData {
/// XML namespace for message response data
#[serde(rename = "xmlns:obj")]
xmlns: String,
/// The name of the domain under transfer
pub name: StringValue,
/// The domain transfer status
#[serde(rename = "trStatus")]
pub transfer_status: StringValue,
/// The epp user who requested the transfer
#[serde(rename = "reID")]
pub requester_id: StringValue,
/// The date of the transfer request
#[serde(rename = "reDate")]
pub requested_at: StringValue,
/// The epp user who should acknowledge the transfer request
#[serde(rename = "acID")]
pub ack_id: StringValue,
/// The date by which the transfer request should be acknowledged
#[serde(rename = "acDate")]
pub ack_by: StringValue,
/// The domain expiry date
#[serde(rename = "exDate")]
pub expiry_date: StringValue,
pub expiring_at: StringValue,
}
/// Type that represents the <resData> tag for message poll response
#[derive(Serialize, Deserialize, Debug)]
pub struct MessagePollResult {
/// Data under the <trnData> tag
#[serde(rename = "trnData")]
pub message_data: MessageDomainTransferData,
}

View File

@ -1,3 +1,5 @@
//! Types to use in serialization to and deserialization from EPP XML
pub mod quick_xml;
use std::{error::Error, fmt::Debug};
@ -19,6 +21,7 @@ pub const EPP_DOMAIN_SCHEMA_LOCATION: &str = "urn:ietf:params:xml:ns:domain-1.0
pub const EPP_VERSION: &str = "1.0";
pub const EPP_LANG: &str = "en";
/// Trait to be implemented by serializers. Currently the only included serializer is `quick-xml`
pub trait EppXml {
type Output: Debug;

View File

@ -1,3 +1,5 @@
//! XML serialization using the `quick-xml` library
use quick_xml::de::from_str;
use quick_xml::se;
use serde::{de::DeserializeOwned, Serialize};

View File

@ -1,6 +1,9 @@
//! Error types to wrap internal errors and make EPP errors easier to read
use crate::epp::response::EppCommandResponseError;
use std::fmt::Display;
/// Error enum holding the possible error types
#[derive(Debug)]
pub enum Error {
EppConnectionError(std::io::Error),
@ -9,6 +12,7 @@ pub enum Error {
Other(String),
}
/// An EPP XML error
#[derive(Debug)]
pub struct EppCommandError {
pub epp_error: EppCommandResponseError,

View File

@ -1,10 +1,11 @@
//! EPP XML to `EppObject` deserialization tests
mod response {
use super::super::get_xml;
use super::super::CLTRID;
use crate::epp::object::StringValueTrait;
use crate::epp::response::{
EppCommandResponse, EppCommandResponseError, EppGreeting, EppLoginResponse,
EppLogoutResponse,
EppCommandResponseError, EppGreeting, EppLoginResponse, EppLogoutResponse,
};
use crate::epp::xml::EppXml;
use crate::epp::*;
@ -286,7 +287,7 @@ mod response {
"2021-07-25T18:11:35.0Z".to_string_value()
);
assert_eq!(
result.create_data.expiry_date,
result.create_data.expiring_at,
"2022-07-25T18:11:34.0Z".to_string_value()
);
assert_eq!(
@ -317,6 +318,9 @@ mod response {
let result = object.data.res_data().unwrap();
let auth_info = result.info_data.auth_info.as_ref().unwrap();
let ns_list = result.info_data.ns.as_ref().unwrap();
let ns = (*ns_list).host_obj.as_ref().unwrap();
let hosts = result.info_data.hosts.as_ref().unwrap();
assert_eq!(object.data.result.code, 1000);
assert_eq!(object.data.result.message, SUCCESS_MSG.to_string_value());
@ -358,6 +362,10 @@ mod response {
result.info_data.contacts[2].contact_type,
"billing".to_string()
);
assert_eq!((*ns)[0], "ns1.eppdev-1.com".to_string_value());
assert_eq!((*ns)[1], "ns2.eppdev-1.com".to_string_value());
assert_eq!((*hosts)[0], "ns1.eppdev-1.com".to_string_value());
assert_eq!((*hosts)[1], "ns2.eppdev-1.com".to_string_value());
assert_eq!(result.info_data.client_id, "eppdev".to_string_value());
assert_eq!(result.info_data.creator_id, "SYSTEM".to_string_value());
assert_eq!(
@ -370,7 +378,7 @@ mod response {
"2021-07-23T15:31:21.0Z".to_string_value()
);
assert_eq!(
result.info_data.expiry_date,
result.info_data.expiring_at,
"2023-07-23T15:31:20.0Z".to_string_value()
);
assert_eq!((*auth_info).password, "epP4uthd#v".to_string_value());
@ -392,7 +400,7 @@ mod response {
assert_eq!(object.data.result.message, SUCCESS_MSG.to_string_value());
assert_eq!(result.renew_data.name, "eppdev-1.com".to_string_value());
assert_eq!(
result.renew_data.expiry_date,
result.renew_data.expiring_at,
"2024-07-23T15:31:20.0Z".to_string_value()
);
assert_eq!(
@ -436,7 +444,7 @@ mod response {
"2021-07-28T15:31:21.0Z".to_string_value()
);
assert_eq!(
result.transfer_data.expiry_date,
result.transfer_data.expiring_at,
"2022-07-02T14:53:19.0Z".to_string_value()
);
assert_eq!(
@ -519,7 +527,7 @@ mod response {
"2021-07-28T15:31:21.0Z".to_string_value()
);
assert_eq!(
result.transfer_data.expiry_date,
result.transfer_data.expiring_at,
"2022-07-02T14:53:19.0Z".to_string_value()
);
assert_eq!(
@ -715,7 +723,7 @@ mod response {
"2021-07-28T15:31:21.0Z".to_string_value()
);
assert_eq!(
result.message_data.expiry_date,
result.message_data.expiring_at,
"2022-07-02T14:53:19.0Z".to_string_value()
);
assert_eq!(

View File

@ -1,3 +1,5 @@
//! Module for automated tests
pub mod de;
pub mod se;
@ -7,6 +9,7 @@ use std::{error::Error, fs::File, io::Read};
const RESOURCES_DIR: &str = "./test/resources";
const CLTRID: &str = "cltrid:1626454866";
/// Reads EPP XML requests and responses from the test/resources directory to run tests on
fn get_xml(path: &str) -> Result<String, Box<dyn Error>> {
let ws_regex = Regex::new(r"[\s]{2,}")?;

View File

@ -1,3 +1,5 @@
//! `EppObject` to EPP XML serialization tests
mod request {
use super::super::get_xml;
use super::super::CLTRID;

View File

@ -14,6 +14,12 @@
<domain:contact type="admin">eppdev-contact-2</domain:contact>
<domain:contact type="tech">eppdev-contact-2</domain:contact>
<domain:contact type="billing">eppdev-contact-2</domain:contact>
<domain:ns>
<domain:hostObj>ns1.eppdev-1.com</domain:hostObj>
<domain:hostObj>ns2.eppdev-1.com</domain:hostObj>
</domain:ns>
<domain:host>ns1.eppdev-1.com</domain:host>
<domain:host>ns2.eppdev-1.com</domain:host>
<domain:clID>eppdev</domain:clID>
<domain:crID>SYSTEM</domain:crID>
<domain:crDate>2021-07-23T15:31:20.0Z</domain:crDate>