From c310e6f7b4a13a29530630fb24d285bd010c2d38 Mon Sep 17 00:00:00 2001 From: Ritesh Chitlangi Date: Sun, 25 Jul 2021 03:10:40 +0800 Subject: [PATCH] added serialization tests --- .gitignore | 2 + epp-client/Cargo.toml | 4 + epp-client/examples/client.rs | 6 +- epp-client/src/config.rs | 68 +- epp-client/src/connection/client.rs | 15 +- epp-client/src/connection/registry.rs | 18 +- epp-client/src/epp.rs | 1 - epp-client/src/epp/request/contact/update.rs | 24 +- epp-client/src/epp/request/domain/update.rs | 4 +- epp-client/src/epp/request/message/ack.rs | 2 +- epp-client/src/epp/response/contact/info.rs | 2 +- epp-client/src/epp/response/domain/check.rs | 3 +- epp-client/src/epp/xml.rs | 2 + epp-client/src/epp/{ => xml}/quick_xml.rs | 0 epp-client/src/lib.rs | 581 +++++++++++++++++- .../test/resources/request/contact/check.xml | 12 + .../test/resources/request/contact/create.xml | 29 + .../test/resources/request/contact/delete.xml | 11 + .../test/resources/request/contact/info.xml | 14 + .../test/resources/request/contact/update.xml | 36 ++ .../test/resources/request/domain/check.xml | 12 + .../test/resources/request/domain/create.xml | 19 + .../request/domain/create_with_host_attr.xml | 29 + .../request/domain/create_with_host_obj.xml | 23 + .../test/resources/request/domain/delete.xml | 11 + .../test/resources/request/domain/info.xml | 11 + .../test/resources/request/domain/renew.xml | 13 + .../request/domain/transfer_approve.xml | 11 + .../request/domain/transfer_cancel.xml | 11 + .../request/domain/transfer_query.xml | 14 + .../request/domain/transfer_reject.xml | 11 + .../request/domain/transfer_request.xml | 15 + .../test/resources/request/domain/update.xml | 22 + epp-client/test/resources/request/hello.xml | 4 + .../test/resources/request/host/check.xml | 12 + .../test/resources/request/host/create.xml | 13 + .../test/resources/request/host/delete.xml | 11 + .../test/resources/request/host/info.xml | 11 + .../test/resources/request/host/update.xml | 20 + epp-client/test/resources/request/login.xml | 22 + epp-client/test/resources/request/logout.xml | 7 + .../test/resources/request/message/ack.xml | 7 + .../test/resources/request/message/poll.xml | 7 + 43 files changed, 1090 insertions(+), 60 deletions(-) rename epp-client/src/epp/{ => xml}/quick_xml.rs (100%) create mode 100644 epp-client/test/resources/request/contact/check.xml create mode 100644 epp-client/test/resources/request/contact/create.xml create mode 100644 epp-client/test/resources/request/contact/delete.xml create mode 100644 epp-client/test/resources/request/contact/info.xml create mode 100644 epp-client/test/resources/request/contact/update.xml create mode 100644 epp-client/test/resources/request/domain/check.xml create mode 100644 epp-client/test/resources/request/domain/create.xml create mode 100644 epp-client/test/resources/request/domain/create_with_host_attr.xml create mode 100644 epp-client/test/resources/request/domain/create_with_host_obj.xml create mode 100644 epp-client/test/resources/request/domain/delete.xml create mode 100644 epp-client/test/resources/request/domain/info.xml create mode 100644 epp-client/test/resources/request/domain/renew.xml create mode 100644 epp-client/test/resources/request/domain/transfer_approve.xml create mode 100644 epp-client/test/resources/request/domain/transfer_cancel.xml create mode 100644 epp-client/test/resources/request/domain/transfer_query.xml create mode 100644 epp-client/test/resources/request/domain/transfer_reject.xml create mode 100644 epp-client/test/resources/request/domain/transfer_request.xml create mode 100644 epp-client/test/resources/request/domain/update.xml create mode 100644 epp-client/test/resources/request/hello.xml create mode 100644 epp-client/test/resources/request/host/check.xml create mode 100644 epp-client/test/resources/request/host/create.xml create mode 100644 epp-client/test/resources/request/host/delete.xml create mode 100644 epp-client/test/resources/request/host/info.xml create mode 100644 epp-client/test/resources/request/host/update.xml create mode 100644 epp-client/test/resources/request/login.xml create mode 100644 epp-client/test/resources/request/logout.xml create mode 100644 epp-client/test/resources/request/message/ack.xml create mode 100644 epp-client/test/resources/request/message/poll.xml diff --git a/.gitignore b/.gitignore index 7aa4d0b..7066410 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ /target **/target +**/certs +/config /epp-client/misc Cargo.lock diff --git a/epp-client/Cargo.toml b/epp-client/Cargo.toml index a95fda1..7e6fea3 100644 --- a/epp-client/Cargo.toml +++ b/epp-client/Cargo.toml @@ -15,8 +15,11 @@ bytes = "1" chrono = "0.4" confy = "0.4" futures = "0.3" +log = "0.4" lazy_static = "1.4" quick-xml = { version = "0.22", features = [ "serialize" ] } +rustls = "0.19" +rustls-pemfile = "0.2" serde = { version = "1.0", features = ["derive"] } tokio = { version = "1.0", features = [ "full" ] } tokio-rustls = "0.22" @@ -25,3 +28,4 @@ webpki-roots = "0.21" [dev-dependencies] tokio-test = "*" +regex = "1.5" diff --git a/epp-client/examples/client.rs b/epp-client/examples/client.rs index f477a8b..bd2ae9a 100644 --- a/epp-client/examples/client.rs +++ b/epp-client/examples/client.rs @@ -52,7 +52,7 @@ async fn update_contact(client: &mut EppClient) { 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, contact_info_res_data.info_data.auth_info.password.to_string().as_str()); + 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); @@ -284,7 +284,7 @@ async fn hello(client: &mut EppClient) { #[tokio::main] async fn main() { - let mut client = match EppClient::new("hexonet").await { + let mut client = match EppClient::new("verisign").await { Ok(client) => { println!("{:?}", client.greeting()); client @@ -296,7 +296,7 @@ async fn main() { // hello(&mut client).await; - // check_domains(&mut client).await; + let response = check_domains(&mut client).await; // check_contacts(&mut client).await; diff --git a/epp-client/src/config.rs b/epp-client/src/config.rs index b5b10b4..d685779 100644 --- a/epp-client/src/config.rs +++ b/epp-client/src/config.rs @@ -1,8 +1,11 @@ use confy; use lazy_static::lazy_static; +use rustls::{Certificate, PrivateKey}; +use rustls_pemfile; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::default; +use std::{fs, io}; lazy_static! { pub static ref CONFIG: EppClientConfig = match confy::load("epp-client") { @@ -11,6 +14,12 @@ lazy_static! { }; } +#[derive(Serialize, Deserialize, Debug)] +pub struct EppClientTlsFiles { + cert_chain: String, + key: String, +} + #[derive(Serialize, Deserialize, Debug)] pub struct EppClientConnection { host: String, @@ -18,17 +27,32 @@ pub struct EppClientConnection { username: String, password: String, ext_uris: Option>, + tls_files: Option, } #[derive(Serialize, Deserialize, Debug)] pub struct EppClientConfig { - pub servers: HashMap, + pub registry: HashMap, } impl default::Default for EppClientConfig { fn default() -> Self { - let servers: HashMap = HashMap::new(); - Self { servers: servers } + let mut registries: HashMap = HashMap::new(); + let registrar = EppClientConnection { + host: "epphost".to_string(), + port: 700, + username: "username".to_string(), + password: "password".to_string(), + ext_uris: Some(vec![]), + tls_files: Some(EppClientTlsFiles { + cert_chain: "/path/to/certificate/chain/pemfile".to_string(), + key: "/path/to/private/key/pemfile".to_string(), + }), + }; + registries.insert("hexonet".to_string(), registrar); + Self { + registry: registries, + } } } @@ -42,10 +66,46 @@ impl EppClientConnection { pub fn ext_uris(&self) -> Option<&Vec> { self.ext_uris.as_ref() } + pub fn tls_files(&self) -> Option<(Vec, PrivateKey)> { + let certificates = self.client_certificate(); + let key = self.key(); + + if certificates == None || key == None { + None + } else { + Some((certificates.unwrap(), key.unwrap())) + } + } + fn client_certificate(&self) -> Option> { + match &self.tls_files { + Some(tls) => Some( + rustls_pemfile::certs(&mut io::BufReader::new( + fs::File::open(tls.cert_chain.to_string()).unwrap(), + )) + .unwrap() + .iter() + .map(|v| Certificate(v.clone())) + .collect(), + ), + None => None, + } + } + fn key(&self) -> Option { + match &self.tls_files { + Some(tls) => Some(rustls::PrivateKey( + rustls_pemfile::rsa_private_keys(&mut io::BufReader::new( + fs::File::open(tls.key.to_string()).unwrap(), + )) + .unwrap()[0] + .clone(), + )), + None => None, + } + } } impl EppClientConfig { pub fn registry(&self, registry: &str) -> Option<&EppClientConnection> { - self.servers.get(registry) + self.registry.get(registry) } } diff --git a/epp-client/src/connection/client.rs b/epp-client/src/connection/client.rs index 7f33792..3b2d1cf 100644 --- a/epp-client/src/connection/client.rs +++ b/epp-client/src/connection/client.rs @@ -100,25 +100,22 @@ impl EppClient { let response = self.connection.transact(&hello_xml).await?; - println!("hello response: {}", response); - Ok(EppGreeting::deserialize(&response)?) } pub async fn transact(&mut self, request: &T) -> Result { let epp_xml = request.serialize()?; - println!("Request:\r\n{}", epp_xml); + debug!("request: {}", epp_xml); let response = self.connection.transact(&epp_xml).await?; - println!("Response:\r\n{}", response); + debug!("response: {}", response); let status = EppCommandResponseStatus::deserialize(&response)?; if status.data.result.code < 2000 { let response = E::deserialize(&response)?; - println!("Response:\r\n{:?}", response); Ok(response) } else { let epp_error = EppCommandResponseError::deserialize(&response)?; @@ -134,15 +131,15 @@ impl EppClient { return String::from(&self.connection.greeting) } - pub fn greeting(&self) -> Result> { - Ok(EppGreeting::deserialize(&self.connection.greeting)?) + pub fn greeting(&self) -> Result { + EppGreeting::deserialize(&self.connection.greeting) } - pub async fn logout(&mut self) { + pub async fn logout(&mut self) -> Result { let client_tr_id = generate_client_tr_id(&self.credentials.0).unwrap(); let epp_logout = EppLogout::new(client_tr_id.as_str()); - self.transact::<_, EppCommandResponse>(&epp_logout).await; + self.transact::<_, EppCommandResponse>(&epp_logout).await } } diff --git a/epp-client/src/connection/registry.rs b/epp-client/src/connection/registry.rs index dc9e276..31f712a 100644 --- a/epp-client/src/connection/registry.rs +++ b/epp-client/src/connection/registry.rs @@ -39,7 +39,7 @@ impl EppConnection { async fn write(&mut self, buf: &Vec) -> Result<(), Box> { let wrote = self.stream.writer.write(buf).await?; - println!("Wrote {} bytes", wrote); + debug!("Wrote {} bytes", wrote); Ok(()) } @@ -66,7 +66,7 @@ impl EppConnection { let buf_size :usize = u32::from_be_bytes(buf).try_into()?; let message_size = buf_size - 4; - println!("Message buffer size: {}", message_size); + debug!("Message buffer size: {}", message_size); let mut buf = BytesMut::with_capacity(4096); let mut read_buf = vec![0u8; 4096]; @@ -75,11 +75,11 @@ impl EppConnection { loop { let read = self.stream.reader.read(&mut read_buf).await?; - println!("Read: {} bytes", read); + debug!("Read: {} bytes", read); buf.extend_from_slice(&read_buf[0..read]); read_size = read_size + read; - println!("Total read: {} bytes", read_size); + debug!("Total read: {} bytes", read_size); if read == 0 { panic!("Unexpected eof") @@ -108,7 +108,7 @@ impl EppConnection { } async fn close(&mut self) -> Result<(), Box> { - println!("Closing ..."); + debug!("Closing {} connection", self.registry); self.stream.writer.shutdown().await?; Ok(()) @@ -124,7 +124,7 @@ impl Drop for EppConnection { pub async fn epp_connect(registry_creds: &EppClientConnection) -> Result { let (host, port) = registry_creds.connection_details(); - println!("{}: {}", host, port); + debug!("Server: {}\r\nPort: {}", host, port); let addr = (host.as_str(), port) .to_socket_addrs()? @@ -137,6 +137,12 @@ pub async fn epp_connect(registry_creds: &EppClientConnection) -> Result>; #[derive(Serialize, Deserialize, Debug)] pub struct ContactChangeInfo { #[serde(rename = "postalInfo")] - postal_info: PostalInfo, - voice: Phone, + postal_info: Option, + voice: Option, fax: Option, - email: StringValue, + email: Option, #[serde(rename = "authInfo")] - auth_info: AuthInfo, + auth_info: Option, } #[derive(Serialize, Deserialize, Debug)] @@ -69,10 +69,10 @@ impl EppContactUpdate { auth_password: &str, ) { self.data.command.contact.change_info = Some(ContactChangeInfo { - email: email.to_string_value(), - postal_info: postal_info, - voice: voice, - auth_info: AuthInfo::new(auth_password), + email: Some(email.to_string_value()), + postal_info: Some(postal_info), + voice: Some(voice), + auth_info: Some(AuthInfo::new(auth_password)), fax: None, }); } @@ -99,11 +99,11 @@ impl EppContactUpdate { match contact_info.data.res_data { Some(res_data) => { self.data.command.contact.change_info = Some(ContactChangeInfo { - email: res_data.info_data.email.clone(), - postal_info: res_data.info_data.postal_info.clone(), - voice: res_data.info_data.voice.clone(), + email: Some(res_data.info_data.email.clone()), + postal_info: Some(res_data.info_data.postal_info.clone()), + voice: Some(res_data.info_data.voice.clone()), fax: res_data.info_data.fax.clone(), - auth_info: res_data.info_data.auth_info.clone(), + auth_info: None, }); Ok(()) } diff --git a/epp-client/src/epp/request/domain/update.rs b/epp-client/src/epp/request/domain/update.rs index 972aeba..2f9b8c3 100644 --- a/epp-client/src/epp/request/domain/update.rs +++ b/epp-client/src/epp/request/domain/update.rs @@ -11,9 +11,9 @@ pub type EppDomainUpdateWithHostAttr = EppObject, #[serde(rename = "authInfo")] - auth_info: AuthInfo, + pub auth_info: Option, } #[derive(Serialize, Deserialize, Debug)] diff --git a/epp-client/src/epp/request/message/ack.rs b/epp-client/src/epp/request/message/ack.rs index f7905a8..10714f0 100644 --- a/epp-client/src/epp/request/message/ack.rs +++ b/epp-client/src/epp/request/message/ack.rs @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize}; pub type EppMessageAck = EppObject>; #[derive(Serialize, Deserialize, Debug, ElementName)] -#[element_name(name = "ack")] +#[element_name(name = "poll")] pub struct MessageAck { op: String, #[serde(rename = "msgID")] diff --git a/epp-client/src/epp/response/contact/info.rs b/epp-client/src/epp/response/contact/info.rs index 834544e..7e7e612 100644 --- a/epp-client/src/epp/response/contact/info.rs +++ b/epp-client/src/epp/response/contact/info.rs @@ -31,7 +31,7 @@ pub struct ContactInfoData { #[serde(rename = "trDate")] pub transferred_at: Option, #[serde(rename = "authInfo")] - pub auth_info: AuthInfo, + pub auth_info: Option, } #[derive(Serialize, Deserialize, Debug)] diff --git a/epp-client/src/epp/response/domain/check.rs b/epp-client/src/epp/response/domain/check.rs index 7212b50..9b2ebf8 100644 --- a/epp-client/src/epp/response/domain/check.rs +++ b/epp-client/src/epp/response/domain/check.rs @@ -15,7 +15,8 @@ pub struct DomainCheck { #[derive(Serialize, Deserialize, Debug)] pub struct DomainCheckDataItem { - pub name: DomainCheck, + #[serde(rename = "name")] + pub domain: DomainCheck, pub reason: Option, } diff --git a/epp-client/src/epp/xml.rs b/epp-client/src/epp/xml.rs index c029d03..1a589f0 100644 --- a/epp-client/src/epp/xml.rs +++ b/epp-client/src/epp/xml.rs @@ -1,3 +1,5 @@ +pub mod quick_xml; + use std::{error::Error, fmt::Debug}; use crate::error; diff --git a/epp-client/src/epp/quick_xml.rs b/epp-client/src/epp/xml/quick_xml.rs similarity index 100% rename from epp-client/src/epp/quick_xml.rs rename to epp-client/src/epp/xml/quick_xml.rs diff --git a/epp-client/src/lib.rs b/epp-client/src/lib.rs index 85c4e4d..48bda56 100644 --- a/epp-client/src/lib.rs +++ b/epp-client/src/lib.rs @@ -1,3 +1,90 @@ +//! EPP Client Library for the Extensible Provisioning Protocol (EPP). +//! +//! ## Description +//! +//! epp-client is a client library for Internet domain registration and management for domain registrars. +//! +//! It supports the following basic Domain, Contact and Host management calls, with plans to add more calls +//! and other EPP extensions in the future, and to eventually be RFC compliant with the EPP protocol. +//! +//! - Domain Check +//! - Domain Create +//! - Domain Info +//! - Domain Update +//! - Domain Delete +//! - Domain Renew +//! - Domain Transfer +//! +//! - Contact Check +//! - Contact Create +//! - Contact Info +//! - Contact Update +//! - Contact Delete +//! +//! - Host Check +//! - Host Create +//! - Host Info +//! - Host Update +//! - Host Delete +//! +//! ## Prerequisites +//! +//! To use the library, you must have an `epp-client/epp-client.toml` config file with the relevant registry +//! credentials in your default user configuration directory on your OS. For Linux, this is the `XDG user directory`, +//! usually located at `$HOME/.config` or defined by the `XDG_CONFIG_HOME` environment variable. +//! +//! An example config looks like this: +//! +//! ```toml +//! [registry.verisign] +//! host = 'epp.verisign-grs.com' +//! port = 700 +//! username = 'username' +//! password = 'password' +//! # service extensions +//! ext_uris = [] +//! +//! [registry.hexonet.tls_files] +//! # the full client certificate chain in PEM format +//! cert_chain = '/path/to/certificate/chain/pemfile' +//! # the RSA private key for your certificate +//! key = '/path/to/private/key/pemfile' +//! ``` +//! +//! ## Operation +//! +//! Once the config is set correctly, you can create a mut variable of type [`EppClient`] to transact +//! with the domain registry +//! +//! ```rust +//! use epp_client::EppClient; +//! use epp_client::epp::{EppDomainCheck, EppDomainCheckResponse}; +//! +//! #[tokio::main] +//! async fn main() { +//! // Create an instance of EppClient, specifying the name of the registry as in +//! // the config file +//! let mut client = match EppClient::new("verisign").await { +//! Ok(client) => client, +//! Err(e) => panic!("Failed to create EppClient: {}", e) +//! }; +//! +//! // Make a domain check call, which returns an object of type EppDomainCheckResponse +//! // that contains the result of the call +//! let domain_check = EppDomainCheck::new(vec!["eppdev.com", "eppdev.net"], "client-trid-12345"); +//! +//! let response = client.transact::<_, EppDomainCheckResponse>(&domain_check).await.unwrap(); +//! +//! // print the availability results +//! response.data.res_data.unwrap().check_data.domain_list +//! .iter() +//! .for_each(|chk| println!("Domain: {}, Available: {}", chk.domain.name, chk.domain.available)); +//! } +//! ``` + +#[macro_use] +extern crate log; + pub mod config; pub mod connection; pub mod epp; @@ -7,30 +94,484 @@ pub use connection::client::EppClient; #[cfg(test)] mod tests { - use super::config; - use super::connection::client::EppClient; + use std::{fs::File, io::Read, error::Error}; + use regex::Regex; - #[test] - fn config() { - let servers = &config::CONFIG.servers; + const RESOURCES_DIR: &str = "./test/resources"; - () + fn get_xml(path: &str) -> Result> { + let ws_regex = Regex::new(r"[\s]{2,}")?; + + let mut f = File::open(format!("{}/{}", RESOURCES_DIR, path))?; + let mut buf = String::new(); + + f.read_to_string(&mut buf)?; + if buf.len() > 0 { + let mat = Regex::new(r"\?>").unwrap().find(&buf.as_str()).unwrap(); + let start = mat.end(); + buf = format!("{}\r\n{}", &buf[..start], ws_regex.replace_all(&buf[start..], "")); + } + Ok(buf) } - macro_rules! aw { - ($e:expr) => { - tokio_test::block_on($e) - }; - } + mod se { + mod request { + use chrono::NaiveDate; + use crate::tests::get_xml; + use crate::epp::object::StringValueTrait; + use crate::epp::object::data::{ + Phone, Address, PostalInfo, ContactStatus, DomainContact, HostAttr, HostAddr, + DomainStatus, AuthInfo, Host, HostStatus + }; + use crate::epp::request::{EppHello, EppLogin, EppLogout}; + use crate::epp::xml::EppXml; + use crate::epp::*; - #[test] - fn connect() { - let mut client = match aw!(EppClient::new("hexonet")) { - Ok(client) => { - println!("{}", client.xml_greeting()); - client - }, - Err(e) => panic!("Error: {}", e) - }; + const CLTRID: &str = "cltrid:1626454866"; + + #[test] + fn hello() { + let xml = get_xml("request/hello.xml").unwrap(); + let object = EppHello::new(); + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn login() { + let ext_uris = Some(vec![ + "http://schema.ispapi.net/epp/xml/keyvalue-1.0".to_string() + ]); + + let xml = get_xml("request/login.xml").unwrap(); + let object = EppLogin::new("username", "password", &ext_uris, CLTRID); + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn logout() { + let xml = get_xml("request/logout.xml").unwrap(); + let object = EppLogout::new(CLTRID); + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn contact_check() { + let xml = get_xml("request/contact/check.xml").unwrap(); + let object = EppContactCheck::new(vec!["eppdev-contact-1", "eppdev-contact-2"], CLTRID); + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn contact_create() { + let xml = get_xml("request/contact/create.xml").unwrap(); + + 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("+33.47237942"); + voice.set_extension("123"); + let mut fax = Phone::new("+33.86698799"); + fax.set_extension("677"); + + let mut object = EppContactCreate::new("eppdev-contact-3", "contact@eppdev.net", postal_info, voice, "eppdev-387323", CLTRID); + object.set_fax(fax); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn contact_info() { + let xml = get_xml("request/contact/info.xml").unwrap(); + + let object = EppContactInfo::new("eppdev-contact-3", "eppdev-387323", CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn contact_update() { + let xml = get_xml("request/contact/update.xml").unwrap(); + + let mut object = EppContactUpdate::new("eppdev-contact-3", CLTRID); + + let street = vec!["58", "Orchid Road"]; + let address = Address::new(street, "Paris", "Paris", "392374", "FR"); + let postal_info = PostalInfo::new("loc", "John Doe", "Acme Widgets", address); + let voice = Phone::new("+33.47237942"); + + object.set_info("newemail@eppdev.net", postal_info, voice, "eppdev-387323"); + let add_statuses = vec![ContactStatus { status: "clientTransferProhibited".to_string() }]; + object.add_statuses(add_statuses); + let remove_statuses = vec![ContactStatus { status: "clientDeleteProhibited".to_string() }]; + object.remove_statuses(remove_statuses); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn contact_delete() { + let xml = get_xml("request/contact/delete.xml").unwrap(); + + let object = EppContactDelete::new("eppdev-contact-3", CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn domain_check() { + let xml = get_xml("request/domain/check.xml").unwrap(); + + let object = EppDomainCheck::new(vec!["eppdev.com", "eppdev.net"], CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn domain_create() { + let xml = get_xml("request/domain/create.xml").unwrap(); + + let contacts = vec![ + DomainContact { + contact_type: "admin".to_string(), + id: "eppdev-contact-3".to_string() + }, + DomainContact { + contact_type: "tech".to_string(), + id: "eppdev-contact-3".to_string() + }, + DomainContact { + contact_type: "billing".to_string(), + id: "eppdev-contact-3".to_string() + } + ]; + + let object = EppDomainCreate::new("eppdev-1.com", 1, "eppdev-contact-3", "epP4uthd#v", contacts, CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn domain_create_with_host_obj() { + let xml = get_xml("request/domain/create_with_host_obj.xml").unwrap(); + + let contacts = vec![ + DomainContact { + contact_type: "admin".to_string(), + id: "eppdev-contact-3".to_string() + }, + DomainContact { + contact_type: "tech".to_string(), + id: "eppdev-contact-3".to_string() + }, + DomainContact { + contact_type: "billing".to_string(), + id: "eppdev-contact-3".to_string() + } + ]; + + let object = EppDomainCreate::new_with_ns("eppdev-1.com", 1, vec!["ns1.test.com", "ns2.test.com"], "eppdev-contact-3", "epP4uthd#v", contacts, CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn domain_create_with_host_attr() { + let xml = get_xml("request/domain/create_with_host_attr.xml").unwrap(); + + let contacts = vec![ + DomainContact { + contact_type: "admin".to_string(), + id: "eppdev-contact-3".to_string() + }, + DomainContact { + contact_type: "tech".to_string(), + id: "eppdev-contact-3".to_string() + }, + DomainContact { + contact_type: "billing".to_string(), + id: "eppdev-contact-3".to_string() + } + ]; + + let host_attr = vec![ + HostAttr { + name: "ns1.eppdev-1.com".to_string_value(), + addresses: None, + }, + HostAttr { + name: "ns2.eppdev-1.com".to_string_value(), + addresses: Some(vec![ + HostAddr::new_v4("177.232.12.58"), + HostAddr::new_v6("2404:6800:4001:801::200e"), + ]) + } + ]; + + let object = EppDomainCreate::new_with_host_attr("eppdev-2.com", 1, host_attr, "eppdev-contact-3", "epP4uthd#v", contacts, CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn domain_info() { + let xml = get_xml("request/domain/info.xml").unwrap(); + + let object = EppDomainInfo::new("eppdev.com", CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn domain_update() { + let xml = get_xml("request/domain/update.xml").unwrap(); + + let mut object = EppDomainUpdate::new("eppdev.com", CLTRID); + + let add = DomainAddRemove { + ns: None, + contacts: None, + statuses: Some(vec![ + DomainStatus { + status: "clientDeleteProhibited".to_string() + } + ]) + }; + + let remove = DomainAddRemove { + ns: None, + contacts: Some(vec![ + DomainContact { + contact_type: "billing".to_string(), + id: "eppdev-contact-2".to_string() + } + ]), + statuses: None, + }; + + let change_info = DomainChangeInfo { + registrant: None, + auth_info: Some(AuthInfo::new("epP5uthd#v")), + }; + + object.add(add); + object.remove(remove); + object.info(change_info); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn domain_delete() { + let xml = get_xml("request/domain/delete.xml").unwrap(); + + let object = EppDomainDelete::new("eppdev.com", CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn domain_renew() { + let xml = get_xml("request/domain/renew.xml").unwrap(); + + let exp_date = NaiveDate::from_ymd(2022, 7, 23); + let object = EppDomainRenew::new("eppdev.com", exp_date, 1, CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn domain_transfer_request() { + let xml = get_xml("request/domain/transfer_request.xml").unwrap(); + + let object = EppDomainTransferRequest::request("testing.com", 1, "epP4uthd#v", CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn domain_transfer_approve() { + let xml = get_xml("request/domain/transfer_approve.xml").unwrap(); + + let object = EppDomainTransferApprove::approve("testing.com", CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn domain_transfer_reject() { + let xml = get_xml("request/domain/transfer_reject.xml").unwrap(); + + let object = EppDomainTransferReject::reject("testing.com", CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn domain_transfer_cancel() { + let xml = get_xml("request/domain/transfer_cancel.xml").unwrap(); + + let object = EppDomainTransferCancel::cancel("testing.com", CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn domain_transfer_query() { + let xml = get_xml("request/domain/transfer_query.xml").unwrap(); + + let object = EppDomainTransferQuery::query("testing.com", "epP4uthd#v", CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn host_check() { + let xml = get_xml("request/host/check.xml").unwrap(); + + let object = EppHostCheck::new(vec!["ns1.eppdev-1.com", "host1.eppdev-1.com"], CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn host_create() { + let xml = get_xml("request/host/create.xml").unwrap(); + + let host = Host { + name: "host1.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 object = EppHostCreate::new(host, CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn host_info() { + let xml = get_xml("request/host/info.xml").unwrap(); + + let object = EppHostInfo::new("ns1.eppdev-1.com", CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn host_update() { + let xml = get_xml("request/host/update.xml").unwrap(); + + 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 object = EppHostUpdate::new("host1.eppdev-1.com", CLTRID); + + object.add(add); + object.remove(remove); + object.info(HostChangeInfo { name: "host2.eppdev-1.com".to_string_value() }); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn host_delete() { + let xml = get_xml("request/host/delete.xml").unwrap(); + + let object = EppHostDelete::new("ns1.eppdev-1.com", CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn message_poll() { + let xml = get_xml("request/message/poll.xml").unwrap(); + + let object = EppMessagePoll::new(CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + + #[test] + fn message_ack() { + let xml = get_xml("request/message/ack.xml").unwrap(); + + let object = EppMessageAck::new(12345, CLTRID); + + let serialized = object.serialize().unwrap(); + + assert_eq!(xml, serialized); + } + } } } diff --git a/epp-client/test/resources/request/contact/check.xml b/epp-client/test/resources/request/contact/check.xml new file mode 100644 index 0000000..55423f1 --- /dev/null +++ b/epp-client/test/resources/request/contact/check.xml @@ -0,0 +1,12 @@ + + + + + + eppdev-contact-1 + eppdev-contact-2 + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/contact/create.xml b/epp-client/test/resources/request/contact/create.xml new file mode 100644 index 0000000..f65c5e0 --- /dev/null +++ b/epp-client/test/resources/request/contact/create.xml @@ -0,0 +1,29 @@ + + + + + + eppdev-contact-3 + + John Doe + Acme Widgets + + 58 + Orchid Road + Paris + Paris + 392374 + FR + + + +33.47237942 + +33.86698799 + contact@eppdev.net + + eppdev-387323 + + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/contact/delete.xml b/epp-client/test/resources/request/contact/delete.xml new file mode 100644 index 0000000..8329d11 --- /dev/null +++ b/epp-client/test/resources/request/contact/delete.xml @@ -0,0 +1,11 @@ + + + + + + eppdev-contact-3 + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/contact/info.xml b/epp-client/test/resources/request/contact/info.xml new file mode 100644 index 0000000..bc53fcb --- /dev/null +++ b/epp-client/test/resources/request/contact/info.xml @@ -0,0 +1,14 @@ + + + + + + eppdev-contact-3 + + eppdev-387323 + + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/contact/update.xml b/epp-client/test/resources/request/contact/update.xml new file mode 100644 index 0000000..33cac27 --- /dev/null +++ b/epp-client/test/resources/request/contact/update.xml @@ -0,0 +1,36 @@ + + + + + + eppdev-contact-3 + + + + + + + + + John Doe + Acme Widgets + + 58 + Orchid Road + Paris + Paris + 392374 + FR + + + +33.47237942 + newemail@eppdev.net + + eppdev-387323 + + + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/domain/check.xml b/epp-client/test/resources/request/domain/check.xml new file mode 100644 index 0000000..028f013 --- /dev/null +++ b/epp-client/test/resources/request/domain/check.xml @@ -0,0 +1,12 @@ + + + + + + eppdev.com + eppdev.net + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/domain/create.xml b/epp-client/test/resources/request/domain/create.xml new file mode 100644 index 0000000..879d6b5 --- /dev/null +++ b/epp-client/test/resources/request/domain/create.xml @@ -0,0 +1,19 @@ + + + + + + eppdev-1.com + 1 + eppdev-contact-3 + eppdev-contact-3 + eppdev-contact-3 + eppdev-contact-3 + + epP4uthd#v + + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/domain/create_with_host_attr.xml b/epp-client/test/resources/request/domain/create_with_host_attr.xml new file mode 100644 index 0000000..1ce71bb --- /dev/null +++ b/epp-client/test/resources/request/domain/create_with_host_attr.xml @@ -0,0 +1,29 @@ + + + + + + eppdev-2.com + 1 + + + ns1.eppdev-1.com + + + ns2.eppdev-1.com + 177.232.12.58 + 2404:6800:4001:801::200e + + + eppdev-contact-3 + eppdev-contact-3 + eppdev-contact-3 + eppdev-contact-3 + + epP4uthd#v + + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/domain/create_with_host_obj.xml b/epp-client/test/resources/request/domain/create_with_host_obj.xml new file mode 100644 index 0000000..4ae819e --- /dev/null +++ b/epp-client/test/resources/request/domain/create_with_host_obj.xml @@ -0,0 +1,23 @@ + + + + + + eppdev-1.com + 1 + + ns1.test.com + ns2.test.com + + eppdev-contact-3 + eppdev-contact-3 + eppdev-contact-3 + eppdev-contact-3 + + epP4uthd#v + + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/domain/delete.xml b/epp-client/test/resources/request/domain/delete.xml new file mode 100644 index 0000000..baf3f77 --- /dev/null +++ b/epp-client/test/resources/request/domain/delete.xml @@ -0,0 +1,11 @@ + + + + + + eppdev.com + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/domain/info.xml b/epp-client/test/resources/request/domain/info.xml new file mode 100644 index 0000000..8ad3d65 --- /dev/null +++ b/epp-client/test/resources/request/domain/info.xml @@ -0,0 +1,11 @@ + + + + + + eppdev.com + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/domain/renew.xml b/epp-client/test/resources/request/domain/renew.xml new file mode 100644 index 0000000..c348265 --- /dev/null +++ b/epp-client/test/resources/request/domain/renew.xml @@ -0,0 +1,13 @@ + + + + + + eppdev.com + 2022-07-23 + 1 + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/domain/transfer_approve.xml b/epp-client/test/resources/request/domain/transfer_approve.xml new file mode 100644 index 0000000..5a6859b --- /dev/null +++ b/epp-client/test/resources/request/domain/transfer_approve.xml @@ -0,0 +1,11 @@ + + + + + + testing.com + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/domain/transfer_cancel.xml b/epp-client/test/resources/request/domain/transfer_cancel.xml new file mode 100644 index 0000000..03e321f --- /dev/null +++ b/epp-client/test/resources/request/domain/transfer_cancel.xml @@ -0,0 +1,11 @@ + + + + + + testing.com + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/domain/transfer_query.xml b/epp-client/test/resources/request/domain/transfer_query.xml new file mode 100644 index 0000000..4ce07b8 --- /dev/null +++ b/epp-client/test/resources/request/domain/transfer_query.xml @@ -0,0 +1,14 @@ + + + + + + testing.com + + epP4uthd#v + + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/domain/transfer_reject.xml b/epp-client/test/resources/request/domain/transfer_reject.xml new file mode 100644 index 0000000..205ca8e --- /dev/null +++ b/epp-client/test/resources/request/domain/transfer_reject.xml @@ -0,0 +1,11 @@ + + + + + + testing.com + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/domain/transfer_request.xml b/epp-client/test/resources/request/domain/transfer_request.xml new file mode 100644 index 0000000..006d44c --- /dev/null +++ b/epp-client/test/resources/request/domain/transfer_request.xml @@ -0,0 +1,15 @@ + + + + + + testing.com + 1 + + epP4uthd#v + + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/domain/update.xml b/epp-client/test/resources/request/domain/update.xml new file mode 100644 index 0000000..b4f31df --- /dev/null +++ b/epp-client/test/resources/request/domain/update.xml @@ -0,0 +1,22 @@ + + + + + + eppdev.com + + + + + eppdev-contact-2 + + + + epP5uthd#v + + + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/hello.xml b/epp-client/test/resources/request/hello.xml new file mode 100644 index 0000000..774f57c --- /dev/null +++ b/epp-client/test/resources/request/hello.xml @@ -0,0 +1,4 @@ + + + + diff --git a/epp-client/test/resources/request/host/check.xml b/epp-client/test/resources/request/host/check.xml new file mode 100644 index 0000000..781e671 --- /dev/null +++ b/epp-client/test/resources/request/host/check.xml @@ -0,0 +1,12 @@ + + + + + + ns1.eppdev-1.com + host1.eppdev-1.com + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/host/create.xml b/epp-client/test/resources/request/host/create.xml new file mode 100644 index 0000000..784c095 --- /dev/null +++ b/epp-client/test/resources/request/host/create.xml @@ -0,0 +1,13 @@ + + + + + + host1.eppdev-1.com + 29.245.122.14 + 2404:6800:4001:801::200e + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/host/delete.xml b/epp-client/test/resources/request/host/delete.xml new file mode 100644 index 0000000..00243a5 --- /dev/null +++ b/epp-client/test/resources/request/host/delete.xml @@ -0,0 +1,11 @@ + + + + + + ns1.eppdev-1.com + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/host/info.xml b/epp-client/test/resources/request/host/info.xml new file mode 100644 index 0000000..d9fccd2 --- /dev/null +++ b/epp-client/test/resources/request/host/info.xml @@ -0,0 +1,11 @@ + + + + + + ns1.eppdev-1.com + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/host/update.xml b/epp-client/test/resources/request/host/update.xml new file mode 100644 index 0000000..a0b9b8c --- /dev/null +++ b/epp-client/test/resources/request/host/update.xml @@ -0,0 +1,20 @@ + + + + + + host1.eppdev-1.com + + 2404:6800:4001:801::200e + + + + + + host2.eppdev-1.com + + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/login.xml b/epp-client/test/resources/request/login.xml new file mode 100644 index 0000000..cfa3bb6 --- /dev/null +++ b/epp-client/test/resources/request/login.xml @@ -0,0 +1,22 @@ + + + + + username + password + + 1.0 + en + + + urn:ietf:params:xml:ns:host-1.0 + urn:ietf:params:xml:ns:contact-1.0 + urn:ietf:params:xml:ns:domain-1.0 + + http://schema.ispapi.net/epp/xml/keyvalue-1.0 + + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/logout.xml b/epp-client/test/resources/request/logout.xml new file mode 100644 index 0000000..a8118d0 --- /dev/null +++ b/epp-client/test/resources/request/logout.xml @@ -0,0 +1,7 @@ + + + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/message/ack.xml b/epp-client/test/resources/request/message/ack.xml new file mode 100644 index 0000000..7cd0ddd --- /dev/null +++ b/epp-client/test/resources/request/message/ack.xml @@ -0,0 +1,7 @@ + + + + + cltrid:1626454866 + + \ No newline at end of file diff --git a/epp-client/test/resources/request/message/poll.xml b/epp-client/test/resources/request/message/poll.xml new file mode 100644 index 0000000..abd0c75 --- /dev/null +++ b/epp-client/test/resources/request/message/poll.xml @@ -0,0 +1,7 @@ + + + + + cltrid:1626454866 + + \ No newline at end of file