2021-07-26 15:51:37 +00:00
|
|
|
//! Types for EPP requests
|
|
|
|
|
2021-07-20 16:43:13 +00:00
|
|
|
pub mod contact;
|
2021-07-20 16:10:56 +00:00
|
|
|
pub mod domain;
|
2021-07-23 19:23:01 +00:00
|
|
|
pub mod host;
|
|
|
|
pub mod message;
|
2021-07-20 16:10:56 +00:00
|
|
|
|
2021-07-25 14:34:01 +00:00
|
|
|
use serde::{ser::SerializeStruct, ser::Serializer, Deserialize, Serialize};
|
2021-07-16 19:16:28 +00:00
|
|
|
use std::error::Error;
|
2021-07-19 17:56:10 +00:00
|
|
|
use std::time::SystemTime;
|
2021-07-16 19:16:28 +00:00
|
|
|
|
2021-07-20 07:45:01 +00:00
|
|
|
use crate::epp::object::{
|
2021-07-29 15:42:36 +00:00
|
|
|
ElementName, EmptyTag, EppObject, Extension, Options, ServiceExtension, Services, StringValue,
|
|
|
|
StringValueTrait,
|
2021-07-20 07:45:01 +00:00
|
|
|
};
|
2021-07-23 19:23:01 +00:00
|
|
|
use crate::epp::xml::{EPP_CONTACT_XMLNS, EPP_DOMAIN_XMLNS, EPP_HOST_XMLNS, EPP_LANG, EPP_VERSION};
|
2021-07-22 10:35:20 +00:00
|
|
|
use epp_client_macros::*;
|
2021-07-16 19:16:28 +00:00
|
|
|
|
2021-07-29 15:42:36 +00:00
|
|
|
/// Type corresponding to the <command> tag in an EPP XML request
|
|
|
|
/// without an <extension> tag
|
|
|
|
pub type Command<T> = CommandWithExtension<T, EmptyTag>;
|
|
|
|
|
2021-07-26 15:51:37 +00:00
|
|
|
/// The EPP Hello request
|
2021-07-20 16:10:56 +00:00
|
|
|
pub type EppHello = EppObject<Hello>;
|
2021-07-26 15:51:37 +00:00
|
|
|
/// The EPP Login Request
|
2021-07-20 16:10:56 +00:00
|
|
|
pub type EppLogin = EppObject<Command<Login>>;
|
2021-07-26 15:51:37 +00:00
|
|
|
/// The EPP Logout request
|
2021-07-20 16:10:56 +00:00
|
|
|
pub type EppLogout = EppObject<Command<Logout>>;
|
2021-07-16 19:16:28 +00:00
|
|
|
|
2021-07-25 14:34:01 +00:00
|
|
|
#[derive(Deserialize, Debug, PartialEq, ElementName)]
|
|
|
|
#[element_name(name = "command")]
|
2021-07-26 19:27:18 +00:00
|
|
|
/// Type corresponding to the <command> tag in an EPP XML request
|
2021-07-29 15:42:36 +00:00
|
|
|
/// with an <extension> tag
|
|
|
|
pub struct CommandWithExtension<T: ElementName, E: ElementName> {
|
2021-07-26 19:27:18 +00:00
|
|
|
/// The instance that will be used to populate the <command> tag
|
2021-07-25 14:34:01 +00:00
|
|
|
pub command: T,
|
2021-07-26 15:51:37 +00:00
|
|
|
/// The client TRID
|
2021-07-29 15:42:36 +00:00
|
|
|
pub extension: Option<Extension<E>>,
|
2021-07-25 14:34:01 +00:00
|
|
|
#[serde(rename = "clTRID")]
|
|
|
|
pub client_tr_id: StringValue,
|
|
|
|
}
|
|
|
|
|
2021-07-29 15:42:36 +00:00
|
|
|
impl<T: ElementName + Serialize, E: ElementName + Serialize> Serialize
|
|
|
|
for CommandWithExtension<T, E>
|
|
|
|
{
|
2021-07-26 15:51:37 +00:00
|
|
|
/// Serializes the generic type T to the proper XML tag (set by the `#[element_name(name = <tagname>)]` attribute) for the request
|
2021-07-25 14:34:01 +00:00
|
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
|
|
where
|
|
|
|
S: Serializer,
|
|
|
|
{
|
|
|
|
let command_name = self.command.element_name();
|
2021-07-29 15:42:36 +00:00
|
|
|
let mut state = serializer.serialize_struct("command", 3)?;
|
2021-07-25 14:34:01 +00:00
|
|
|
state.serialize_field(command_name, &self.command)?;
|
2021-07-29 15:42:36 +00:00
|
|
|
state.serialize_field("extension", &self.extension)?;
|
2021-07-25 14:34:01 +00:00
|
|
|
state.serialize_field("clTRID", &self.client_tr_id)?;
|
|
|
|
state.end()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-29 15:42:36 +00:00
|
|
|
impl<T: ElementName> Command<T> {
|
|
|
|
/// Creates a new <command> tag for an EPP document
|
|
|
|
pub fn new(command: T, client_tr_id: &str) -> Command<T> {
|
|
|
|
Command {
|
2021-10-27 22:45:32 +00:00
|
|
|
command,
|
2021-07-29 15:42:36 +00:00
|
|
|
extension: None,
|
|
|
|
client_tr_id: client_tr_id.to_string_value(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: ElementName, E: ElementName> CommandWithExtension<T, E> {
|
|
|
|
/// Creates a new <command> tag for an EPP document with a containing <extension> tag
|
|
|
|
pub fn build(command: T, ext: E, client_tr_id: &str) -> CommandWithExtension<T, E> {
|
|
|
|
CommandWithExtension {
|
2021-10-27 22:45:32 +00:00
|
|
|
command,
|
2021-07-29 15:42:36 +00:00
|
|
|
extension: Some(Extension { data: ext }),
|
|
|
|
client_tr_id: client_tr_id.to_string_value(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-26 15:51:37 +00:00
|
|
|
/// Basic client TRID generation function. Mainly used for testing. Users of the library should use their own clTRID generation function.
|
2021-07-20 16:10:56 +00:00
|
|
|
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()))
|
2021-07-16 19:16:28 +00:00
|
|
|
}
|
|
|
|
|
2021-07-22 10:35:20 +00:00
|
|
|
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
|
|
|
|
#[element_name(name = "hello")]
|
2021-07-26 15:51:37 +00:00
|
|
|
/// Type corresponding to the <hello> tag in an EPP XML hello request
|
2021-07-16 19:16:28 +00:00
|
|
|
pub struct Hello;
|
|
|
|
|
2021-07-20 16:43:13 +00:00
|
|
|
impl EppHello {
|
2021-07-26 15:51:37 +00:00
|
|
|
/// Creates a new Epp Hello request
|
2021-07-20 16:43:13 +00:00
|
|
|
pub fn new() -> EppHello {
|
|
|
|
EppObject::build(Hello {})
|
2021-07-20 16:10:56 +00:00
|
|
|
}
|
2021-07-16 19:16:28 +00:00
|
|
|
}
|
|
|
|
|
2021-10-27 23:00:37 +00:00
|
|
|
impl Default for EppHello {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self::new()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-22 10:35:20 +00:00
|
|
|
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
|
|
|
|
#[element_name(name = "login")]
|
2021-07-26 19:27:18 +00:00
|
|
|
/// Type corresponding to the <login> tag in an EPP XML login request
|
2021-07-16 19:16:28 +00:00
|
|
|
pub struct Login {
|
2021-07-26 15:51:37 +00:00
|
|
|
/// The username to use for the login
|
2021-07-16 19:16:28 +00:00
|
|
|
#[serde(rename(serialize = "clID", deserialize = "clID"))]
|
|
|
|
username: StringValue,
|
2021-07-26 15:51:37 +00:00
|
|
|
/// The password to use for the login
|
2021-07-16 19:16:28 +00:00
|
|
|
#[serde(rename = "pw", default)]
|
|
|
|
password: StringValue,
|
2021-07-26 15:51:37 +00:00
|
|
|
/// Data under the <options> tag
|
2021-07-20 07:45:01 +00:00
|
|
|
options: Options,
|
2021-07-26 15:51:37 +00:00
|
|
|
/// Data under the <svcs> tag
|
2021-07-16 19:16:28 +00:00
|
|
|
#[serde(rename = "svcs")]
|
|
|
|
services: Services,
|
|
|
|
}
|
|
|
|
|
2021-07-20 16:43:13 +00:00
|
|
|
impl EppLogin {
|
2021-07-26 15:51:37 +00:00
|
|
|
/// Creates a new EPP Login request
|
2021-07-23 19:23:01 +00:00
|
|
|
pub fn new(
|
|
|
|
username: &str,
|
|
|
|
password: &str,
|
|
|
|
ext_uris: &Option<Vec<String>>,
|
|
|
|
client_tr_id: &str,
|
|
|
|
) -> EppLogin {
|
2021-11-02 21:34:13 +00:00
|
|
|
let ext_uris = ext_uris.as_ref().map(|uris| {
|
|
|
|
uris.iter()
|
|
|
|
.map(|u| u.to_string_value())
|
|
|
|
.collect::<Vec<StringValue>>()
|
|
|
|
});
|
2021-07-23 19:23:01 +00:00
|
|
|
|
2021-07-16 19:16:28 +00:00
|
|
|
let login = Login {
|
|
|
|
username: username.to_string_value(),
|
|
|
|
password: password.to_string_value(),
|
2021-07-20 07:45:01 +00:00
|
|
|
options: Options {
|
2021-07-16 19:16:28 +00:00
|
|
|
version: EPP_VERSION.to_string_value(),
|
|
|
|
lang: EPP_LANG.to_string_value(),
|
|
|
|
},
|
|
|
|
services: Services {
|
|
|
|
obj_uris: vec![
|
2021-07-23 19:23:01 +00:00
|
|
|
EPP_HOST_XMLNS.to_string_value(),
|
|
|
|
EPP_CONTACT_XMLNS.to_string_value(),
|
|
|
|
EPP_DOMAIN_XMLNS.to_string_value(),
|
2021-07-16 19:16:28 +00:00
|
|
|
],
|
2021-10-27 22:45:32 +00:00
|
|
|
svc_ext: Some(ServiceExtension { ext_uris }),
|
2021-07-16 19:16:28 +00:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2021-07-20 16:43:13 +00:00
|
|
|
EppObject::build(Command::<Login> {
|
2021-07-20 16:10:56 +00:00
|
|
|
command: login,
|
2021-07-29 15:42:36 +00:00
|
|
|
extension: None,
|
2021-07-16 19:16:28 +00:00
|
|
|
client_tr_id: client_tr_id.to_string_value(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-07-26 15:51:37 +00:00
|
|
|
/// Sets the <options> tag data
|
|
|
|
pub fn options(&mut self, options: Options) {
|
2021-07-20 16:43:13 +00:00
|
|
|
self.data.command.options = options;
|
2021-07-16 19:16:28 +00:00
|
|
|
}
|
|
|
|
|
2021-07-26 15:51:37 +00:00
|
|
|
/// Sets the <svcs> tag data
|
|
|
|
pub fn services(&mut self, services: Services) {
|
2021-07-20 16:43:13 +00:00
|
|
|
self.data.command.services = services;
|
2021-07-16 19:16:28 +00:00
|
|
|
}
|
|
|
|
}
|
2021-07-19 18:17:57 +00:00
|
|
|
|
2021-07-22 10:35:20 +00:00
|
|
|
#[derive(Serialize, Deserialize, Debug, PartialEq, ElementName)]
|
|
|
|
#[element_name(name = "logout")]
|
2021-07-26 19:27:18 +00:00
|
|
|
/// Type corresponding to the <logout> tag in an EPP XML logout request
|
2021-07-19 18:17:57 +00:00
|
|
|
pub struct Logout;
|
|
|
|
|
2021-07-20 16:43:13 +00:00
|
|
|
impl EppLogout {
|
2021-07-26 15:51:37 +00:00
|
|
|
/// Creates a new EPP Logout request
|
2021-07-20 16:43:13 +00:00
|
|
|
pub fn new(client_tr_id: &str) -> EppLogout {
|
|
|
|
EppObject::build(Command::<Logout> {
|
2021-07-20 16:10:56 +00:00
|
|
|
command: Logout,
|
2021-07-29 15:42:36 +00:00
|
|
|
extension: None,
|
2021-07-19 18:17:57 +00:00
|
|
|
client_tr_id: client_tr_id.to_string_value(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|