added basic domain operations

This commit is contained in:
Ritesh Chitlangi 2021-07-24 00:47:41 +08:00
parent 5c9afa665b
commit f4ee674161
24 changed files with 763 additions and 108 deletions

View File

@ -6,11 +6,11 @@ use quote::quote;
fn element_name_macro(ast: &syn::DeriveInput) -> TokenStream { fn element_name_macro(ast: &syn::DeriveInput) -> TokenStream {
let name = &ast.ident; let name = &ast.ident;
let mut elem_name = ast.ident.to_string(); let mut elem_name = ast.ident.to_string();
let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl(); let (impl_generics, type_generics, _) = &ast.generics.split_for_impl();
if ast.attrs.len() > 0 { if ast.attrs.len() > 0 {
let attribute = &ast.attrs[0]; let attribute = &ast.attrs[0];
let meta = match attribute.parse_meta() { match attribute.parse_meta() {
Ok(syn::Meta::List(meta)) => { Ok(syn::Meta::List(meta)) => {
if meta.nested.len() > 0 { if meta.nested.len() > 0 {
elem_name = match &meta.nested[0] { elem_name = match &meta.nested[0] {

View File

@ -12,6 +12,7 @@ path = "examples/client.rs"
[dependencies] [dependencies]
epp-client-macros = { path = "../epp-client-macros" } epp-client-macros = { path = "../epp-client-macros" }
bytes = "1" bytes = "1"
chrono = "0.4"
confy = "0.4" confy = "0.4"
futures = "0.3" futures = "0.3"
lazy_static = "1.4" lazy_static = "1.4"

View File

@ -1,31 +1,29 @@
use std::{error::Error, time::SystemTime};
use chrono::NaiveDate;
use epp_client::EppClient; use epp_client::EppClient;
use epp_client::{epp::request::generate_client_tr_id, epp::xml::EppXml}; use epp_client::epp::object::{StringValueTrait};
use epp_client::epp::object::data::{PostalInfo, Address, Phone, DomainContact, ContactStatus}; use epp_client::{epp::request, epp::xml::EppXml};
use epp_client::epp::EppDomainCheck; use epp_client::epp::object::data::{
use epp_client::epp::EppDomainCheckResponse; PostalInfo, Address, Phone, DomainContact, ContactStatus, DomainStatus, HostObjList, HostAttrList, HostAttr, HostAddr
use epp_client::epp::EppContactCheck; };
use epp_client::epp::EppContactCheckResponse; use epp_client::epp::*;
use epp_client::epp::EppContactCreate;
use epp_client::epp::EppContactCreateResponse; fn gen_client_tr_id(username: &str) -> Result<String, Box<dyn Error>> {
use epp_client::epp::EppContactInfo; let timestamp = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?;
use epp_client::epp::EppContactInfoResponse; Ok(format!("{}:{}", username, timestamp.as_secs()))
use epp_client::epp::EppContactUpdate; }
use epp_client::epp::EppContactUpdateResponse;
use epp_client::epp::EppContactDelete;
use epp_client::epp::EppContactDeleteResponse;
use epp_client::epp::EppDomainCreate;
use epp_client::epp::EppDomainCreateResponse;
async fn check_domains(client: &mut EppClient) { async fn check_domains(client: &mut EppClient) {
let domains = vec!["eppdev.com", "hexonet.net"]; let domains = vec!["eppdev.com", "hexonet.net"];
let domain_check = EppDomainCheck::new(domains, generate_client_tr_id("eppdev").unwrap().as_str()); let domain_check = EppDomainCheck::new(domains, gen_client_tr_id("eppdev").unwrap().as_str());
client.transact::<_, EppDomainCheckResponse>(&domain_check).await.unwrap(); client.transact::<_, EppDomainCheckResponse>(&domain_check).await.unwrap();
} }
async fn check_contacts(client: &mut EppClient) { async fn check_contacts(client: &mut EppClient) {
let contacts = vec!["eppdev-contact-1", "eppdev-contact-2"]; let contacts = vec!["eppdev-contact-1", "eppdev-contact-2"];
let contact_check = EppContactCheck::new(contacts, generate_client_tr_id("eppdev").unwrap().as_str()); let contact_check = EppContactCheck::new(contacts, gen_client_tr_id("eppdev").unwrap().as_str());
client.transact::<_, EppContactCheckResponse>(&contact_check).await.unwrap(); client.transact::<_, EppContactCheckResponse>(&contact_check).await.unwrap();
} }
@ -39,7 +37,7 @@ async fn create_contact(client: &mut EppClient) {
let mut fax = Phone::new("+47.86698799"); let mut fax = Phone::new("+47.86698799");
fax.set_extension("677"); fax.set_extension("677");
let mut contact_create = EppContactCreate::new("eppdev-contact-2", "contact@eppdev.net", postal_info, voice, "eppdev-387323", generate_client_tr_id("eppdev").unwrap().as_str()); let mut contact_create = EppContactCreate::new("eppdev-contact-3", "contact@eppdev.net", postal_info, voice, "eppdev-387323", gen_client_tr_id("eppdev").unwrap().as_str());
contact_create.set_fax(fax); contact_create.set_fax(fax);
// println!("xml: {}", contact_create.serialize().unwrap()); // println!("xml: {}", contact_create.serialize().unwrap());
@ -48,10 +46,10 @@ async fn create_contact(client: &mut EppClient) {
} }
async fn update_contact(client: &mut EppClient) { async fn update_contact(client: &mut EppClient) {
let contact_info = EppContactInfo::new("eppdev-contact-1", "eppdev-387323", generate_client_tr_id("eppdev").unwrap().as_str()); 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 contact_info_response = client.transact::<_, EppContactInfoResponse>(&contact_info).await.unwrap();
let mut contact_update = EppContactUpdate::new("eppdev-contact-1", generate_client_tr_id("eppdev").unwrap().as_str()); 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(); 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, contact_info_res_data.info_data.auth_info.password.to_string().as_str());
let add_statuses = vec![ContactStatus { status: "clientTransferProhibited".to_string() }]; let add_statuses = vec![ContactStatus { status: "clientTransferProhibited".to_string() }];
@ -63,13 +61,13 @@ async fn update_contact(client: &mut EppClient) {
} }
async fn query_contact(client: &mut EppClient) { async fn query_contact(client: &mut EppClient) {
let mut contact_info = EppContactInfo::new("eppdev-contact-2", "eppdev-387323", generate_client_tr_id("eppdev").unwrap().as_str()); let mut contact_info = EppContactInfo::new("eppdev-contact-2", "eppdev-387323", gen_client_tr_id("eppdev").unwrap().as_str());
client.transact::<_, EppContactInfoResponse>(&contact_info).await.unwrap(); client.transact::<_, EppContactInfoResponse>(&contact_info).await.unwrap();
} }
async fn delete_contact(client: &mut EppClient) { async fn delete_contact(client: &mut EppClient) {
let contact_delete = EppContactDelete::new("eppdev-contact-1", generate_client_tr_id("eppdev").unwrap().as_str()); let contact_delete = EppContactDelete::new("eppdev-contact-1", gen_client_tr_id("eppdev").unwrap().as_str());
client.transact::<_, EppContactDeleteResponse>(&contact_delete).await.unwrap(); client.transact::<_, EppContactDeleteResponse>(&contact_delete).await.unwrap();
} }
@ -89,15 +87,112 @@ async fn create_domain(client: &mut EppClient) {
id: "eppdev-contact-2".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, generate_client_tr_id("eppdev").unwrap().as_str()); // 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.com", 1, "eppdev-contact-2", "epP4uthd#v", contacts, generate_client_tr_id("eppdev").unwrap().as_str()); let domain_create = EppDomainCreate::new("eppdev-1.com", 1, "eppdev-contact-2", "epP4uthd#v", contacts, gen_client_tr_id("eppdev").unwrap().as_str());
// println!("{}", domain_create.serialize().unwrap()); // println!("{}", domain_create.serialize().unwrap());
client.transact::<_, EppDomainCreateResponse>(&domain_create).await.unwrap(); 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);
// println!("{}", domain_update.serialize().unwrap());
client.transact::<_, EppDomainUpdateResponse>(&domain_update).await.unwrap();
}
async fn delete_domain(client: &mut EppClient) {
let domain_delete = EppDomainDelete::new("eppdev.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(2022, 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 hello(client: &mut EppClient) { async fn hello(client: &mut EppClient) {
let greeting = client.hello().await.unwrap(); let greeting = client.hello().await.unwrap();
@ -114,6 +209,8 @@ async fn main() {
Err(e) => panic!("Error: {}", e) Err(e) => panic!("Error: {}", e)
}; };
// client.set_client_tr_id_fn(gen_client_tr_id);
// hello(&mut client).await; // hello(&mut client).await;
// check_domains(&mut client).await; // check_domains(&mut client).await;
@ -129,4 +226,22 @@ async fn main() {
// delete_contact(&mut client).await; // delete_contact(&mut client).await;
// create_domain(&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;
} }

View File

@ -1,6 +1,8 @@
use futures::executor::block_on; use futures::executor::block_on;
use std::{error::Error, fmt::Debug}; use std::{error::Error, fmt::Debug};
// use std::time::SystemTime;
use std::sync::mpsc; use std::sync::mpsc;
// use std::sync::Arc;
use crate::config::CONFIG; use crate::config::CONFIG;
use crate::connection::registry::{epp_connect, EppConnection}; use crate::connection::registry::{epp_connect, EppConnection};
@ -8,7 +10,6 @@ use crate::error;
use crate::epp::request::{generate_client_tr_id, EppHello, EppLogin, EppLogout}; use crate::epp::request::{generate_client_tr_id, EppHello, EppLogin, EppLogout};
use crate::epp::response::{EppGreeting, EppCommandResponseStatus, EppCommandResponse, EppCommandResponseError}; use crate::epp::response::{EppGreeting, EppCommandResponseStatus, EppCommandResponse, EppCommandResponseError};
use crate::epp::xml::EppXml; use crate::epp::xml::EppXml;
use crate::epp::object::{ElementName, EppObject};
async fn connect(registry: &'static str) -> Result<EppClient, Box<dyn Error>> { async fn connect(registry: &'static str) -> Result<EppClient, Box<dyn Error>> {
let registry_creds = match CONFIG.registry(registry) { let registry_creds = match CONFIG.registry(registry) {
@ -40,9 +41,27 @@ async fn connect(registry: &'static str) -> Result<EppClient, Box<dyn Error>> {
pub struct EppClient { pub struct EppClient {
credentials: (String, String), credentials: (String, String),
connection: EppConnection, connection: EppConnection,
// pub client_tr_id_fn: Arc<dyn Fn(&EppClient) -> String + Send + Sync>,
} }
// fn default_client_tr_id_fn(client: &EppClient) -> String {
// let timestamp = match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
// Ok(time) => time,
// Err(e) => panic!("Error in client TRID gen function: {}", e)
// };
// format!("{}:{}", &client.username(), timestamp.as_secs())
// }
impl EppClient { impl EppClient {
pub fn username(&self) -> String {
self.credentials.0.to_string()
}
// pub fn set_client_tr_id_fn<F>(&mut self, func: F)
// where F: Fn(&EppClient) -> String + Send + Sync + 'static {
// self.client_tr_id_fn = Arc::new(func);
// }
pub async fn new(registry: &'static str) -> Result<EppClient, Box<dyn Error>> { pub async fn new(registry: &'static str) -> Result<EppClient, Box<dyn Error>> {
connect(registry).await connect(registry).await
} }
@ -50,13 +69,14 @@ impl EppClient {
async fn build(connection: EppConnection, credentials: (String, String)) -> Result<EppClient, Box<dyn Error>> { async fn build(connection: EppConnection, credentials: (String, String)) -> Result<EppClient, Box<dyn Error>> {
let mut client = EppClient { let mut client = EppClient {
connection: connection, connection: connection,
credentials: credentials credentials: credentials,
// client_tr_id_fn: Arc::new(default_client_tr_id_fn),
}; };
let client_tr_id = generate_client_tr_id(&client.credentials.0)?; let client_tr_id = generate_client_tr_id(&client.credentials.0)?;
let login_request = EppLogin::new(&client.credentials.0, &client.credentials.1, client_tr_id.as_str()); let login_request = EppLogin::new(&client.credentials.0, &client.credentials.1, client_tr_id.as_str());
client.transact::<EppLogin, EppCommandResponse>(&login_request).await?; client.transact::<_, EppCommandResponse>(&login_request).await?;
Ok(client) Ok(client)
} }
@ -109,7 +129,7 @@ impl EppClient {
let client_tr_id = generate_client_tr_id(&self.credentials.0).unwrap(); let client_tr_id = generate_client_tr_id(&self.credentials.0).unwrap();
let epp_logout = EppLogout::new(client_tr_id.as_str()); let epp_logout = EppLogout::new(client_tr_id.as_str());
self.transact::<EppLogout, EppCommandResponse>(&epp_logout).await; self.transact::<_, EppCommandResponse>(&epp_logout).await;
} }
} }

View File

@ -59,12 +59,6 @@ impl EppConnection {
self.write(&buf).await self.write(&buf).await
} }
async fn read(&mut self) -> Result<Vec<u8>, Box<dyn Error>> {
let mut buf = vec![0u8; 4096];
self.stream.reader.read(&mut buf).await?;
Ok(buf)
}
async fn read_epp_response(&mut self) -> Result<Vec<u8>, Box<dyn Error>> { async fn read_epp_response(&mut self) -> Result<Vec<u8>, Box<dyn Error>> {
let mut buf = [0u8; 4]; let mut buf = [0u8; 4];
self.stream.reader.read_exact(&mut buf).await?; self.stream.reader.read_exact(&mut buf).await?;

View File

@ -12,6 +12,12 @@ pub use request::contact::info::*;
pub use request::contact::update::*; pub use request::contact::update::*;
pub use request::domain::check::*; pub use request::domain::check::*;
pub use request::domain::create::*; pub use request::domain::create::*;
pub use request::domain::delete::*;
pub use request::domain::info::*;
pub use request::domain::renew::*;
pub use request::domain::transfer::*;
pub use request::domain::update::*;
pub use response::contact::check::*; pub use response::contact::check::*;
pub use response::contact::create::*; pub use response::contact::create::*;
pub use response::contact::delete::*; pub use response::contact::delete::*;
@ -19,3 +25,8 @@ pub use response::contact::info::*;
pub use response::contact::update::*; pub use response::contact::update::*;
pub use response::domain::check::*; pub use response::domain::check::*;
pub use response::domain::create::*; pub use response::domain::create::*;
pub use response::domain::delete::*;
pub use response::domain::info::*;
pub use response::domain::renew::*;
pub use response::domain::transfer::*;
pub use response::domain::update::*;

View File

@ -30,6 +30,12 @@ impl StringValueTrait for &str {
} }
} }
impl StringValueTrait for String {
fn to_string_value(&self) -> StringValue {
StringValue(self.to_string())
}
}
pub trait ElementName { pub trait ElementName {
fn element_name(&self) -> &'static str; fn element_name(&self) -> &'static str;
} }

View File

@ -1,6 +1,63 @@
use crate::epp::object::{StringValue, StringValueTrait}; use crate::epp::object::{StringValue, StringValueTrait};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
pub enum DomainNsList {
HostAttrList(HostAttrList),
HostObjList(HostObjList),
}
#[derive(Serialize, Deserialize, Debug)]
pub struct HostAddr {
#[serde(rename = "ip")]
ip_version: Option<String>,
#[serde(rename = "$value")]
address: String,
}
impl HostAddr {
pub fn new(ip_version: &str, address: &str) -> HostAddr {
HostAddr {
ip_version: Some(ip_version.to_string()),
address: address.to_string(),
}
}
pub fn new_v4(address: &str) -> HostAddr {
HostAddr {
ip_version: Some("v4".to_string()),
address: address.to_string(),
}
}
pub fn new_v6(address: &str) -> HostAddr {
HostAddr {
ip_version: Some("v6".to_string()),
address: address.to_string(),
}
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct HostAttr {
#[serde(rename = "hostName")]
pub name: StringValue,
#[serde(rename = "hostAddr")]
pub addresses: Option<Vec<HostAddr>>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct HostAttrList {
#[serde(rename = "hostAttr")]
pub hosts: Vec<HostAttr>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct HostObjList {
#[serde(rename = "hostObj")]
pub hosts: Vec<StringValue>,
}
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct DomainContact { pub struct DomainContact {
#[serde(rename = "$value")] #[serde(rename = "$value")]
@ -29,6 +86,12 @@ impl Period {
} }
} }
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainStatus {
#[serde(rename = "s")]
pub status: String,
}
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct ContactStatus { pub struct ContactStatus {
#[serde(rename = "s")] #[serde(rename = "s")]

View File

@ -17,7 +17,7 @@ impl<T: Serialize + DeserializeOwned + ElementName + Debug> EppXml for EppObject
} }
fn deserialize(epp_xml: &str) -> Result<Self::Output, error::Error> { fn deserialize(epp_xml: &str) -> Result<Self::Output, error::Error> {
let mut object: Self::Output = match from_str(epp_xml) { let object: Self::Output = match from_str(epp_xml) {
Ok(v) => v, Ok(v) => v,
Err(e) => { Err(e) => {
return Err(error::Error::EppDeserializationError( return Err(error::Error::EppDeserializationError(

View File

@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
pub type EppContactDelete = EppObject<Command<ContactDelete>>; pub type EppContactDelete = EppObject<Command<ContactDelete>>;
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct ContactData { pub struct ContactDeleteData {
pub xmlns: String, pub xmlns: String,
pub id: StringValue, pub id: StringValue,
} }
@ -17,14 +17,14 @@ pub struct ContactData {
#[element_name(name = "delete")] #[element_name(name = "delete")]
pub struct ContactDelete { pub struct ContactDelete {
#[serde(rename = "delete")] #[serde(rename = "delete")]
contact: ContactData, contact: ContactDeleteData,
} }
impl EppContactDelete { impl EppContactDelete {
pub fn new(id: &str, client_tr_id: &str) -> EppContactDelete { pub fn new(id: &str, client_tr_id: &str) -> EppContactDelete {
EppObject::build(Command::<ContactDelete> { EppObject::build(Command::<ContactDelete> {
command: ContactDelete { command: ContactDelete {
contact: ContactData { contact: ContactDeleteData {
xmlns: EPP_CONTACT_XMLNS.to_string(), xmlns: EPP_CONTACT_XMLNS.to_string(),
id: id.to_string_value(), id: id.to_string_value(),
}, },

View File

@ -1,2 +1,7 @@
pub mod check; pub mod check;
pub mod create; pub mod create;
pub mod delete;
pub mod info;
pub mod renew;
pub mod transfer;
pub mod update;

View File

@ -1,7 +1,9 @@
use epp_client_macros::*; use epp_client_macros::*;
use crate::epp::command::Command; use crate::epp::command::Command;
use crate::epp::object::data::{AuthInfo, DomainContact, Period}; use crate::epp::object::data::{
AuthInfo, DomainContact, HostAttr, HostAttrList, HostObjList, Period,
};
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait}; use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::xml::EPP_DOMAIN_XMLNS; use crate::epp::xml::EPP_DOMAIN_XMLNS;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -9,59 +11,8 @@ use serde::{Deserialize, Serialize};
pub type EppDomainCreate = EppObject<Command<DomainCreate<HostObjList>>>; pub type EppDomainCreate = EppObject<Command<DomainCreate<HostObjList>>>;
pub type EppDomainCreateWithHostAttr = EppObject<Command<DomainCreate<HostAttrList>>>; pub type EppDomainCreateWithHostAttr = EppObject<Command<DomainCreate<HostAttrList>>>;
pub enum HostType {
HostObj,
HostAttr,
}
pub trait HostList {
fn new(ns: Vec<&str>) -> Self;
}
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct HostAttr { pub struct DomainCreateData<T> {
#[serde(rename = "hostName")]
host_name: StringValue,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct HostAttrList {
#[serde(rename = "hostAttr")]
hosts: Vec<HostAttr>,
}
impl HostList for HostAttrList {
fn new(ns: Vec<&str>) -> HostAttrList {
let ns_list = ns
.iter()
.map(|n| HostAttr {
host_name: n.to_string_value(),
})
.collect::<Vec<HostAttr>>();
HostAttrList { hosts: ns_list }
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct HostObjList {
#[serde(rename = "hostObj")]
hosts: Vec<StringValue>,
}
impl HostList for HostObjList {
fn new(ns: Vec<&str>) -> HostObjList {
let ns_list = ns
.iter()
.map(|n| n.to_string_value())
.collect::<Vec<StringValue>>();
HostObjList { hosts: ns_list }
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainData<T> {
xmlns: String, xmlns: String,
name: StringValue, name: StringValue,
period: Period, period: Period,
@ -77,7 +28,7 @@ pub struct DomainData<T> {
#[element_name(name = "create")] #[element_name(name = "create")]
pub struct DomainCreate<T> { pub struct DomainCreate<T> {
#[serde(rename = "create")] #[serde(rename = "create")]
domain: DomainData<T>, domain: DomainCreateData<T>,
} }
impl EppDomainCreate { impl EppDomainCreate {
@ -90,13 +41,18 @@ impl EppDomainCreate {
contacts: Vec<DomainContact>, contacts: Vec<DomainContact>,
client_tr_id: &str, client_tr_id: &str,
) -> EppDomainCreate { ) -> EppDomainCreate {
let ns_list = ns
.iter()
.map(|n| n.to_string_value())
.collect::<Vec<StringValue>>();
EppObject::build(Command::<DomainCreate<HostObjList>> { EppObject::build(Command::<DomainCreate<HostObjList>> {
command: DomainCreate { command: DomainCreate {
domain: DomainData { domain: DomainCreateData {
xmlns: EPP_DOMAIN_XMLNS.to_string(), xmlns: EPP_DOMAIN_XMLNS.to_string(),
name: name.to_string_value(), name: name.to_string_value(),
period: Period::new(period), period: Period::new(period),
ns: Some(HostObjList::new(ns)), ns: Some(HostObjList { hosts: ns_list }),
registrant: Some(registrant_id.to_string_value()), registrant: Some(registrant_id.to_string_value()),
auth_info: AuthInfo::new(auth_password), auth_info: AuthInfo::new(auth_password),
contacts: Some(contacts), contacts: Some(contacts),
@ -116,7 +72,7 @@ impl EppDomainCreate {
) -> EppDomainCreate { ) -> EppDomainCreate {
EppObject::build(Command::<DomainCreate<HostObjList>> { EppObject::build(Command::<DomainCreate<HostObjList>> {
command: DomainCreate { command: DomainCreate {
domain: DomainData { domain: DomainCreateData {
xmlns: EPP_DOMAIN_XMLNS.to_string(), xmlns: EPP_DOMAIN_XMLNS.to_string(),
name: name.to_string_value(), name: name.to_string_value(),
period: Period::new(period), period: Period::new(period),
@ -138,7 +94,7 @@ impl EppDomainCreate {
) -> EppDomainCreate { ) -> EppDomainCreate {
EppObject::build(Command::<DomainCreate<HostObjList>> { EppObject::build(Command::<DomainCreate<HostObjList>> {
command: DomainCreate { command: DomainCreate {
domain: DomainData { domain: DomainCreateData {
xmlns: EPP_DOMAIN_XMLNS.to_string(), xmlns: EPP_DOMAIN_XMLNS.to_string(),
name: name.to_string_value(), name: name.to_string_value(),
period: Period::new(period), period: Period::new(period),
@ -155,7 +111,7 @@ impl EppDomainCreate {
pub fn new_with_host_attr( pub fn new_with_host_attr(
name: &str, name: &str,
period: u16, period: u16,
ns: Vec<&str>, ns: Vec<HostAttr>,
registrant_id: &str, registrant_id: &str,
auth_password: &str, auth_password: &str,
contacts: Vec<DomainContact>, contacts: Vec<DomainContact>,
@ -163,11 +119,11 @@ impl EppDomainCreate {
) -> EppDomainCreateWithHostAttr { ) -> EppDomainCreateWithHostAttr {
EppObject::build(Command::<DomainCreate<HostAttrList>> { EppObject::build(Command::<DomainCreate<HostAttrList>> {
command: DomainCreate { command: DomainCreate {
domain: DomainData { domain: DomainCreateData {
xmlns: EPP_DOMAIN_XMLNS.to_string(), xmlns: EPP_DOMAIN_XMLNS.to_string(),
name: name.to_string_value(), name: name.to_string_value(),
period: Period::new(period), period: Period::new(period),
ns: Some(HostAttrList::new(ns)), ns: Some(HostAttrList { hosts: ns }),
registrant: Some(registrant_id.to_string_value()), registrant: Some(registrant_id.to_string_value()),
auth_info: AuthInfo::new(auth_password), auth_info: AuthInfo::new(auth_password),
contacts: Some(contacts), contacts: Some(contacts),

View File

@ -0,0 +1,35 @@
use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::xml::EPP_DOMAIN_XMLNS;
use serde::{Deserialize, Serialize};
pub type EppDomainDelete = EppObject<Command<DomainDelete>>;
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainDeleteData {
pub xmlns: String,
pub name: StringValue,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "delete")]
pub struct DomainDelete {
#[serde(rename = "delete")]
domain: DomainDeleteData,
}
impl EppDomainDelete {
pub fn new(name: &str, client_tr_id: &str) -> EppDomainDelete {
EppObject::build(Command::<DomainDelete> {
command: DomainDelete {
domain: DomainDeleteData {
xmlns: EPP_DOMAIN_XMLNS.to_string(),
name: name.to_string_value(),
},
},
client_tr_id: client_tr_id.to_string_value(),
})
}
}

View File

@ -0,0 +1,46 @@
use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::{ElementName, EppObject, StringValueTrait};
use crate::epp::xml::EPP_DOMAIN_XMLNS;
use serde::{Deserialize, Serialize};
pub type EppDomainInfo = EppObject<Command<DomainInfo>>;
#[derive(Serialize, Deserialize, Debug)]
pub struct Domain {
hosts: String,
#[serde(rename = "$value")]
name: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainInfoData {
xmlns: String,
#[serde(rename = "name")]
domain: Domain,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "info")]
pub struct DomainInfo {
#[serde(rename = "info")]
info: DomainInfoData,
}
impl EppDomainInfo {
pub fn new(name: &str, client_tr_id: &str) -> EppDomainInfo {
EppObject::build(Command::<DomainInfo> {
command: DomainInfo {
info: DomainInfoData {
xmlns: EPP_DOMAIN_XMLNS.to_string(),
domain: Domain {
hosts: "all".to_string(),
name: name.to_string(),
},
},
},
client_tr_id: client_tr_id.to_string_value(),
})
}
}

View File

@ -0,0 +1,56 @@
use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::data::Period;
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::xml::EPP_DOMAIN_XMLNS;
use chrono::NaiveDate;
use serde::{Deserialize, Serialize};
pub type EppDomainRenew = EppObject<Command<DomainRenew>>;
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainRenewData {
xmlns: String,
name: StringValue,
#[serde(rename = "curExpDate")]
current_expiry_date: StringValue,
period: Period,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "renew")]
pub struct DomainRenew {
#[serde(rename = "renew")]
domain: DomainRenewData,
}
impl EppDomainRenew {
pub fn new(
name: &str,
current_expiry_date: NaiveDate,
years: u16,
client_tr_id: &str,
) -> EppDomainRenew {
let exp_date_str = current_expiry_date
.format("%Y-%m-%d")
.to_string()
.to_string_value();
EppObject::build(Command::<DomainRenew> {
command: DomainRenew {
domain: DomainRenewData {
xmlns: EPP_DOMAIN_XMLNS.to_string(),
name: name.to_string_value(),
current_expiry_date: exp_date_str,
period: Period::new(years),
},
},
client_tr_id: client_tr_id.to_string_value(),
})
}
pub fn set_period(&mut self, period: Period) {
self.data.command.domain.period = period;
}
}

View File

@ -0,0 +1,125 @@
use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::data::{AuthInfo, Period};
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::xml::EPP_DOMAIN_XMLNS;
use serde::{Deserialize, Serialize};
pub type EppDomainTransferRequest = EppObject<Command<DomainTransfer>>;
pub type EppDomainTransferApprove = EppObject<Command<DomainTransfer>>;
pub type EppDomainTransferReject = EppObject<Command<DomainTransfer>>;
pub type EppDomainTransferCancel = EppObject<Command<DomainTransfer>>;
pub type EppDomainTransferQuery = EppObject<Command<DomainTransfer>>;
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainTransferData {
xmlns: String,
name: StringValue,
period: Option<Period>,
#[serde(rename = "authInfo")]
auth_info: Option<AuthInfo>,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "transfer")]
pub struct DomainTransfer {
#[serde(rename = "op")]
operation: String,
#[serde(rename = "transfer")]
domain: DomainTransferData,
}
impl EppDomainTransferRequest {
pub fn request(
name: &str,
years: u16,
auth_password: &str,
client_tr_id: &str,
) -> EppDomainTransferRequest {
EppObject::build(Command::<DomainTransfer> {
command: DomainTransfer {
operation: "request".to_string(),
domain: DomainTransferData {
xmlns: EPP_DOMAIN_XMLNS.to_string(),
name: name.to_string_value(),
period: Some(Period::new(years)),
auth_info: Some(AuthInfo::new(auth_password)),
},
},
client_tr_id: client_tr_id.to_string_value(),
})
}
pub fn set_period(&mut self, period: Period) {
self.data.command.domain.period = Some(period);
}
}
impl EppDomainTransferApprove {
pub fn approve(name: &str, client_tr_id: &str) -> EppDomainTransferApprove {
EppObject::build(Command::<DomainTransfer> {
command: DomainTransfer {
operation: "approve".to_string(),
domain: DomainTransferData {
xmlns: EPP_DOMAIN_XMLNS.to_string(),
name: name.to_string_value(),
period: None,
auth_info: None,
},
},
client_tr_id: client_tr_id.to_string_value(),
})
}
}
impl EppDomainTransferCancel {
pub fn cancel(name: &str, client_tr_id: &str) -> EppDomainTransferCancel {
EppObject::build(Command::<DomainTransfer> {
command: DomainTransfer {
operation: "cancel".to_string(),
domain: DomainTransferData {
xmlns: EPP_DOMAIN_XMLNS.to_string(),
name: name.to_string_value(),
period: None,
auth_info: None,
},
},
client_tr_id: client_tr_id.to_string_value(),
})
}
}
impl EppDomainTransferReject {
pub fn reject(name: &str, client_tr_id: &str) -> EppDomainTransferReject {
EppObject::build(Command::<DomainTransfer> {
command: DomainTransfer {
operation: "reject".to_string(),
domain: DomainTransferData {
xmlns: EPP_DOMAIN_XMLNS.to_string(),
name: name.to_string_value(),
period: None,
auth_info: None,
},
},
client_tr_id: client_tr_id.to_string_value(),
})
}
}
impl EppDomainTransferQuery {
pub fn query(name: &str, auth_password: &str, client_tr_id: &str) -> EppDomainTransferQuery {
EppObject::build(Command::<DomainTransfer> {
command: DomainTransfer {
operation: "query".to_string(),
domain: DomainTransferData {
xmlns: EPP_DOMAIN_XMLNS.to_string(),
name: name.to_string_value(),
period: None,
auth_info: Some(AuthInfo::new(auth_password)),
},
},
client_tr_id: client_tr_id.to_string_value(),
})
}
}

View File

@ -0,0 +1,103 @@
use epp_client_macros::*;
use crate::epp::command::Command;
use crate::epp::object::data::{AuthInfo, DomainContact, DomainStatus, HostAttrList, HostObjList};
use crate::epp::object::{ElementName, EppObject, StringValue, StringValueTrait};
use crate::epp::xml::EPP_DOMAIN_XMLNS;
use serde::{Deserialize, Serialize};
pub type EppDomainUpdate = EppObject<Command<DomainUpdate<HostObjList>>>;
pub type EppDomainUpdateWithHostAttr = EppObject<Command<DomainUpdate<HostAttrList>>>;
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainChangeInfo {
registrant: StringValue,
#[serde(rename = "authInfo")]
auth_info: AuthInfo,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainAddRemove<T> {
#[serde(rename = "ns")]
pub ns: Option<T>,
#[serde(rename = "contact")]
pub contacts: Option<Vec<DomainContact>>,
#[serde(rename = "status")]
pub statuses: Option<Vec<DomainStatus>>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainUpdateData<T> {
xmlns: String,
name: StringValue,
add: Option<DomainAddRemove<T>>,
#[serde(rename = "rem")]
remove: Option<DomainAddRemove<T>>,
#[serde(rename = "chg")]
change_info: Option<DomainChangeInfo>,
}
#[derive(Serialize, Deserialize, Debug, ElementName)]
#[element_name(name = "update")]
pub struct DomainUpdate<T> {
#[serde(rename = "update")]
domain: DomainUpdateData<T>,
}
impl EppDomainUpdate {
pub fn new(name: &str, client_tr_id: &str) -> EppDomainUpdate {
EppObject::build(Command::<DomainUpdate<HostObjList>> {
command: DomainUpdate {
domain: DomainUpdateData {
xmlns: EPP_DOMAIN_XMLNS.to_string(),
name: name.to_string_value(),
add: None,
remove: None,
change_info: None,
},
},
client_tr_id: client_tr_id.to_string_value(),
})
}
pub fn info(&mut self, info: DomainChangeInfo) {
self.data.command.domain.change_info = Some(info);
}
pub fn add(&mut self, add: DomainAddRemove<HostObjList>) {
self.data.command.domain.add = Some(add);
}
pub fn remove(&mut self, remove: DomainAddRemove<HostObjList>) {
self.data.command.domain.remove = Some(remove);
}
}
impl EppDomainUpdateWithHostAttr {
pub fn new(name: &str, client_tr_id: &str) -> EppDomainUpdateWithHostAttr {
EppObject::build(Command::<DomainUpdate<HostAttrList>> {
command: DomainUpdate {
domain: DomainUpdateData {
xmlns: EPP_DOMAIN_XMLNS.to_string(),
name: name.to_string_value(),
add: None,
remove: None,
change_info: None,
},
},
client_tr_id: client_tr_id.to_string_value(),
})
}
pub fn info(&mut self, info: DomainChangeInfo) {
self.data.command.domain.change_info = Some(info);
}
pub fn add(&mut self, add: DomainAddRemove<HostAttrList>) {
self.data.command.domain.add = Some(add);
}
pub fn remove(&mut self, remove: DomainAddRemove<HostAttrList>) {
self.data.command.domain.remove = Some(remove);
}
}

View File

@ -151,12 +151,6 @@ pub struct ResponseTRID {
pub server_tr_id: StringValue, pub server_tr_id: StringValue,
} }
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct ErrorResponseTRID {
#[serde(rename = "svTRID")]
pub server_tr_id: StringValue,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)] #[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]
#[element_name(name = "response")] #[element_name(name = "response")]

View File

@ -1,2 +1,7 @@
pub mod check; pub mod check;
pub mod create; pub mod create;
pub mod delete;
pub mod info;
pub mod renew;
pub mod transfer;
pub mod update;

View File

@ -0,0 +1,3 @@
use crate::epp::response::EppCommandResponse;
pub type EppDomainDeleteResponse = EppCommandResponse;

View File

@ -0,0 +1,57 @@
use serde::{Deserialize, Serialize};
use crate::epp::object::data::{AuthInfo, DomainContact, DomainNsList, DomainStatus};
use crate::epp::object::{EppObject, StringValue};
use crate::epp::response::CommandResponse;
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>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainInfoData {
#[serde(rename = "xmlns:domain")]
xmlns: String,
pub name: StringValue,
pub roid: StringValue,
pub status: Vec<DomainStatus>,
pub registrant: StringValue,
#[serde(rename = "contact")]
pub contacts: Vec<DomainContact>,
pub ns: Option<DomainNsList>,
pub host: Option<Vec<StringValue>>,
#[serde(rename = "clID")]
pub client_id: StringValue,
#[serde(rename = "crID")]
pub creator_id: StringValue,
#[serde(rename = "crDate")]
pub created_at: StringValue,
#[serde(rename = "upID")]
pub updater_id: StringValue,
#[serde(rename = "upDate")]
pub updated_at: StringValue,
#[serde(rename = "exDate")]
pub expiry_date: StringValue,
#[serde(rename = "trDate")]
pub transferred_at: Option<StringValue>,
#[serde(rename = "authInfo")]
pub auth_info: AuthInfo,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainInfoResult {
#[serde(rename = "infData")]
pub check_data: DomainInfoData,
}

View File

@ -0,0 +1,21 @@
use serde::{Deserialize, Serialize};
use crate::epp::object::{EppObject, StringValue};
use crate::epp::response::CommandResponse;
pub type EppDomainRenewResponse = EppObject<CommandResponse<DomainRenewResult>>;
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainRenewData {
#[serde(rename = "xmlns:domain")]
xmlns: String,
name: StringValue,
#[serde(rename = "exDate")]
expiry_date: StringValue,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainRenewResult {
#[serde(rename = "renData")]
pub renew_data: DomainRenewData,
}

View File

@ -0,0 +1,36 @@
use serde::{Deserialize, Serialize};
use crate::epp::object::{EppObject, StringValue};
use crate::epp::response::CommandResponse;
use crate::epp::response::EppCommandResponse;
pub type EppDomainTransferRequestResponse = EppObject<CommandResponse<DomainTransferResult>>;
pub type EppDomainTransferApproveResponse = EppCommandResponse;
pub type EppDomainTransferRejectResponse = EppCommandResponse;
pub type EppDomainTransferCancelResponse = EppCommandResponse;
pub type EppDomainTransferQueryResponse = EppObject<CommandResponse<DomainTransferResult>>;
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainTransferData {
#[serde(rename = "xmlns:domain")]
xmlns: String,
name: StringValue,
#[serde(rename = "trStatus")]
transfer_status: StringValue,
#[serde(rename = "reID")]
requester_id: StringValue,
#[serde(rename = "reDate")]
request_date: StringValue,
#[serde(rename = "acID")]
responder_id: StringValue,
#[serde(rename = "acDate")]
respond_by_date: StringValue,
#[serde(rename = "exDate")]
expiry_date: StringValue,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct DomainTransferResult {
#[serde(rename = "trnData")]
pub transfer_data: DomainTransferData,
}

View File

@ -0,0 +1,3 @@
use crate::epp::response::EppCommandResponse;
pub type EppDomainUpdateResponse = EppCommandResponse;