mirror of
https://github.com/vbrandl/bind9-api.git
synced 2024-11-22 11:13:49 +01:00
Add documentation and fail builds on missing docs
This commit is contained in:
parent
6eacab00f9
commit
9ec59bf5e3
@ -38,6 +38,9 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
|
//! Helper crate for cryptographic operations.
|
||||||
|
|
||||||
extern crate failure;
|
extern crate failure;
|
||||||
extern crate hex;
|
extern crate hex;
|
||||||
@ -53,16 +56,19 @@ use ring::{digest, hmac};
|
|||||||
|
|
||||||
type Result<T> = std::result::Result<T, Error>;
|
type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
|
/// Converts a byte slice to a lowercase hex string.
|
||||||
pub fn bytes_to_hex_str(bytes: &[u8]) -> Result<String> {
|
pub fn bytes_to_hex_str(bytes: &[u8]) -> Result<String> {
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
bytes.write_hex(&mut output)?;
|
bytes.write_hex(&mut output)?;
|
||||||
Ok(output)
|
Ok(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Converts a hey string to a vec of bytes.
|
||||||
pub fn hex_str_to_bytes(hex_str: &str) -> Result<Vec<u8>> {
|
pub fn hex_str_to_bytes(hex_str: &str) -> Result<Vec<u8>> {
|
||||||
Ok(Vec::from_hex(hex_str)?)
|
Ok(Vec::from_hex(hex_str)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Verifies a HMAC SHA256 signature.
|
||||||
pub fn verify_signature(key: &[u8], msg: &[u8], signature: &[u8]) -> bool {
|
pub fn verify_signature(key: &[u8], msg: &[u8], signature: &[u8]) -> bool {
|
||||||
let key = hmac::VerificationKey::new(&digest::SHA256, key);
|
let key = hmac::VerificationKey::new(&digest::SHA256, key);
|
||||||
hmac::verify(&key, msg, signature)
|
hmac::verify(&key, msg, signature)
|
||||||
@ -70,6 +76,7 @@ pub fn verify_signature(key: &[u8], msg: &[u8], signature: &[u8]) -> bool {
|
|||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a HMAC SHA256 signature.
|
||||||
pub fn sign(key: &[u8], msg: &[u8]) -> Vec<u8> {
|
pub fn sign(key: &[u8], msg: &[u8]) -> Vec<u8> {
|
||||||
let key = hmac::SigningKey::new(&digest::SHA256, key);
|
let key = hmac::SigningKey::new(&digest::SHA256, key);
|
||||||
let signature = hmac::sign(&key, msg);
|
let signature = hmac::sign(&key, msg);
|
||||||
|
211
data/src/lib.rs
211
data/src/lib.rs
@ -38,30 +38,110 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
|
//! This crate provides definitions for shared types between the client and the server
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate failure;
|
extern crate failure;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate hyper;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
/// The name of the API token header: `X-Api-Token`
|
||||||
pub const TOKEN_HEADER: &str = "X-Api-Token";
|
pub const TOKEN_HEADER: &str = "X-Api-Token";
|
||||||
|
|
||||||
header! { (XApiToken, TOKEN_HEADER) => [String] }
|
/// Enumeration of DNS record types
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Deserialize, Serialize, Debug, Clone, Copy)]
|
#[derive(Eq, PartialEq, Deserialize, Serialize, Debug, Clone, Copy)]
|
||||||
pub enum Record {
|
pub enum Record {
|
||||||
|
/// A record
|
||||||
A,
|
A,
|
||||||
|
/// AAAA record
|
||||||
AAAA,
|
AAAA,
|
||||||
|
/// AFSDB record
|
||||||
|
AFSDB,
|
||||||
|
/// APL record
|
||||||
|
APL,
|
||||||
|
/// CAA record
|
||||||
|
CAA,
|
||||||
|
/// CDNSKEY record
|
||||||
|
CDNSKEY,
|
||||||
|
/// CDS record
|
||||||
|
CDS,
|
||||||
|
/// CERT record
|
||||||
|
CERT,
|
||||||
|
/// CNAME record
|
||||||
|
CNAME,
|
||||||
|
/// DHCID record
|
||||||
|
DHCID,
|
||||||
|
/// DLV record
|
||||||
|
DLV,
|
||||||
|
/// DNAME record
|
||||||
|
DNAME,
|
||||||
|
/// DNSKEY record
|
||||||
|
DNSKEY,
|
||||||
|
/// DS record
|
||||||
|
DS,
|
||||||
|
/// HIP record
|
||||||
|
HIP,
|
||||||
|
/// IPSECKEY record
|
||||||
|
IPSECKEY,
|
||||||
|
/// KEY record
|
||||||
|
KEY,
|
||||||
|
/// KX record
|
||||||
|
KX,
|
||||||
|
/// LOC record
|
||||||
|
LOC,
|
||||||
|
/// MX record
|
||||||
|
MX,
|
||||||
|
/// NAPTR record
|
||||||
|
NAPTR,
|
||||||
|
/// NS record
|
||||||
|
NS,
|
||||||
|
/// NSEC record
|
||||||
|
NSEC,
|
||||||
|
/// NSEC3 record
|
||||||
|
NSEC3,
|
||||||
|
/// NSEC3PARAM record
|
||||||
|
NSEC3PARAM,
|
||||||
|
/// OPENPGPKEY record
|
||||||
|
OPENPGPKEY,
|
||||||
|
/// PTR record
|
||||||
PTR,
|
PTR,
|
||||||
|
/// RRSIG record
|
||||||
|
RRSIG,
|
||||||
|
/// RP record
|
||||||
|
RP,
|
||||||
|
/// SIG record
|
||||||
|
SIG,
|
||||||
|
/// SOA record
|
||||||
|
SOA,
|
||||||
|
/// SRV record
|
||||||
|
SRV,
|
||||||
|
/// SSHFP record
|
||||||
|
SSHFP,
|
||||||
|
/// TA record
|
||||||
|
TA,
|
||||||
|
/// TKEY record
|
||||||
|
TKEY,
|
||||||
|
/// TLSA record
|
||||||
|
TLSA,
|
||||||
|
/// TSIG record
|
||||||
|
TSIG,
|
||||||
|
/// TXT record
|
||||||
TXT,
|
TXT,
|
||||||
|
/// URI record
|
||||||
|
URI,
|
||||||
|
/// ALIAS record
|
||||||
|
ALIAS,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Error types that the API can yield
|
||||||
#[derive(Debug, Fail)]
|
#[derive(Debug, Fail)]
|
||||||
pub enum ApiError {
|
pub enum ApiError {
|
||||||
|
/// Error while parsing a DNS record
|
||||||
#[fail(display = "Parse record error")]
|
#[fail(display = "Parse record error")]
|
||||||
ParseRecord,
|
ParseRecord,
|
||||||
|
/// Error while handling a request
|
||||||
#[fail(display = "API Error")]
|
#[fail(display = "API Error")]
|
||||||
RequestError,
|
RequestError,
|
||||||
}
|
}
|
||||||
@ -73,8 +153,44 @@ impl std::str::FromStr for Record {
|
|||||||
match s {
|
match s {
|
||||||
"A" | "a" => Ok(Record::A),
|
"A" | "a" => Ok(Record::A),
|
||||||
"AAAA" | "aaaa" => Ok(Record::AAAA),
|
"AAAA" | "aaaa" => Ok(Record::AAAA),
|
||||||
"TXT" | "txt" => Ok(Record::TXT),
|
"AFSDB" | "afsdb" => Ok(Record::AFSDB),
|
||||||
|
"APL" | "apl" => Ok(Record::APL),
|
||||||
|
"CAA" | "caa" => Ok(Record::CAA),
|
||||||
|
"CDNSKEY" | "cdnskey" => Ok(Record::CDNSKEY),
|
||||||
|
"CDS" | "cds" => Ok(Record::CDS),
|
||||||
|
"CERT" | "cert" => Ok(Record::CERT),
|
||||||
|
"CNAME" | "cname" => Ok(Record::CNAME),
|
||||||
|
"DHCID" | "dhcid" => Ok(Record::DHCID),
|
||||||
|
"DLV" | "dlv" => Ok(Record::DLV),
|
||||||
|
"DNAME" | "dname" => Ok(Record::DNAME),
|
||||||
|
"DNSKEY" | "dnskey" => Ok(Record::DNSKEY),
|
||||||
|
"DS" | "ds" => Ok(Record::DS),
|
||||||
|
"HIP" | "hip" => Ok(Record::HIP),
|
||||||
|
"IPSECKEY" | "ipseckey" => Ok(Record::IPSECKEY),
|
||||||
|
"KEY" | "key" => Ok(Record::KEY),
|
||||||
|
"KX" | "kx" => Ok(Record::KX),
|
||||||
|
"LOC" | "loc" => Ok(Record::LOC),
|
||||||
|
"MX" | "mx" => Ok(Record::MX),
|
||||||
|
"NAPTR" | "naptr" => Ok(Record::NAPTR),
|
||||||
|
"NS" | "ns" => Ok(Record::NS),
|
||||||
|
"NSEC" | "nsec" => Ok(Record::NSEC),
|
||||||
|
"NSEC3" | "nsec3" => Ok(Record::NSEC3),
|
||||||
|
"NSEC3PARAM" | "nsec3param" => Ok(Record::NSEC3PARAM),
|
||||||
|
"OPENPGPKEY" | "openpgpkey" => Ok(Record::OPENPGPKEY),
|
||||||
"PTR" | "ptr" => Ok(Record::PTR),
|
"PTR" | "ptr" => Ok(Record::PTR),
|
||||||
|
"RRSIG" | "rrsig" => Ok(Record::RRSIG),
|
||||||
|
"RP" | "rp" => Ok(Record::RP),
|
||||||
|
"SIG" | "sig" => Ok(Record::SIG),
|
||||||
|
"SOA" | "soa" => Ok(Record::SOA),
|
||||||
|
"SRV" | "srv" => Ok(Record::SRV),
|
||||||
|
"SSHFP" | "sshfp" => Ok(Record::SSHFP),
|
||||||
|
"TA" | "ta" => Ok(Record::TA),
|
||||||
|
"TKEY" | "tkey" => Ok(Record::TKEY),
|
||||||
|
"TLSA" | "tlsa" => Ok(Record::TLSA),
|
||||||
|
"TSIG" | "tsig" => Ok(Record::TSIG),
|
||||||
|
"TXT" | "txt" => Ok(Record::TXT),
|
||||||
|
"URI" | "uri" => Ok(Record::URI),
|
||||||
|
"ALIAS" | "alias" => Ok(Record::ALIAS),
|
||||||
_ => Err(ApiError::ParseRecord),
|
_ => Err(ApiError::ParseRecord),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,13 +204,51 @@ impl std::fmt::Display for Record {
|
|||||||
match *self {
|
match *self {
|
||||||
Record::A => "A",
|
Record::A => "A",
|
||||||
Record::AAAA => "AAAA",
|
Record::AAAA => "AAAA",
|
||||||
|
Record::AFSDB => "AFSDB",
|
||||||
|
Record::APL => "APL",
|
||||||
|
Record::CAA => "CAA",
|
||||||
|
Record::CDNSKEY => "CDNSKEY",
|
||||||
|
Record::CDS => "CDS",
|
||||||
|
Record::CERT => "CERT",
|
||||||
|
Record::CNAME => "CNAME",
|
||||||
|
Record::DHCID => "DHCID",
|
||||||
|
Record::DLV => "DLV",
|
||||||
|
Record::DNAME => "DNAME",
|
||||||
|
Record::DNSKEY => "DNSKEY",
|
||||||
|
Record::DS => "DS",
|
||||||
|
Record::HIP => "HIP",
|
||||||
|
Record::IPSECKEY => "IPSECKEY",
|
||||||
|
Record::KEY => "KEY",
|
||||||
|
Record::KX => "KX",
|
||||||
|
Record::LOC => "LOC",
|
||||||
|
Record::MX => "MX",
|
||||||
|
Record::NAPTR => "NAPTR",
|
||||||
|
Record::NS => "NS",
|
||||||
|
Record::NSEC => "NSEC",
|
||||||
|
Record::NSEC3 => "NSEC3",
|
||||||
|
Record::NSEC3PARAM => "NSEC3PARAM",
|
||||||
|
Record::OPENPGPKEY => "OPENPGPKEY",
|
||||||
Record::PTR => "PTR",
|
Record::PTR => "PTR",
|
||||||
|
Record::RRSIG => "RRSIG",
|
||||||
|
Record::RP => "RP",
|
||||||
|
Record::SIG => "SIG",
|
||||||
|
Record::SOA => "SOA",
|
||||||
|
Record::SRV => "SRV",
|
||||||
|
Record::SSHFP => "SSHFP",
|
||||||
|
Record::TA => "TA",
|
||||||
|
Record::TKEY => "TKEY",
|
||||||
|
Record::TLSA => "TLSA",
|
||||||
|
Record::TSIG => "TSIG",
|
||||||
Record::TXT => "TXT",
|
Record::TXT => "TXT",
|
||||||
|
Record::URI => "URI",
|
||||||
|
Record::ALIAS => "ALIAS",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Data for an update request containing the domain name, record type,
|
||||||
|
/// record value and TTL.
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub struct Update {
|
pub struct Update {
|
||||||
name: String,
|
name: String,
|
||||||
@ -104,36 +258,42 @@ pub struct Update {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Update {
|
impl Update {
|
||||||
|
/// Creates a new Update object.
|
||||||
pub fn new(name: String, value: String, record: Record, ttl: u32) -> Self {
|
pub fn new(name: String, value: String, record: Record, ttl: u32) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
value,
|
value,
|
||||||
record,
|
record,
|
||||||
ttl: ttl,
|
ttl,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a reference to the name field.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn name(&self) -> &str {
|
pub fn name(&self) -> &str {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a reference to the value field.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn value(&self) -> &str {
|
pub fn value(&self) -> &str {
|
||||||
&self.value
|
&self.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the record field.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn record(&self) -> Record {
|
pub fn record(&self) -> Record {
|
||||||
self.record
|
self.record
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the TTL.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn ttl(&self) -> u32 {
|
pub fn ttl(&self) -> u32 {
|
||||||
self.ttl
|
self.ttl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Data of a delete request, containing the domain name and record type.
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub struct Delete {
|
pub struct Delete {
|
||||||
name: String,
|
name: String,
|
||||||
@ -141,15 +301,18 @@ pub struct Delete {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Delete {
|
impl Delete {
|
||||||
|
/// Creates a new Delete object.
|
||||||
pub fn new(name: String, record: Record) -> Self {
|
pub fn new(name: String, record: Record) -> Self {
|
||||||
Self { name, record }
|
Self { name, record }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a reference to the name field.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn name(&self) -> &str {
|
pub fn name(&self) -> &str {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the record type.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn record(&self) -> Record {
|
pub fn record(&self) -> Record {
|
||||||
self.record
|
self.record
|
||||||
@ -177,8 +340,44 @@ mod tests {
|
|||||||
fn record_to_str_and_parse_equals_input() {
|
fn record_to_str_and_parse_equals_input() {
|
||||||
assert!(validate_record_parsing(Record::A));
|
assert!(validate_record_parsing(Record::A));
|
||||||
assert!(validate_record_parsing(Record::AAAA));
|
assert!(validate_record_parsing(Record::AAAA));
|
||||||
|
assert!(validate_record_parsing(Record::AFSDB));
|
||||||
|
assert!(validate_record_parsing(Record::APL));
|
||||||
|
assert!(validate_record_parsing(Record::CAA));
|
||||||
|
assert!(validate_record_parsing(Record::CDNSKEY));
|
||||||
|
assert!(validate_record_parsing(Record::CDS));
|
||||||
|
assert!(validate_record_parsing(Record::CERT));
|
||||||
|
assert!(validate_record_parsing(Record::CNAME));
|
||||||
|
assert!(validate_record_parsing(Record::DHCID));
|
||||||
|
assert!(validate_record_parsing(Record::DLV));
|
||||||
|
assert!(validate_record_parsing(Record::DNAME));
|
||||||
|
assert!(validate_record_parsing(Record::DNSKEY));
|
||||||
|
assert!(validate_record_parsing(Record::DS));
|
||||||
|
assert!(validate_record_parsing(Record::HIP));
|
||||||
|
assert!(validate_record_parsing(Record::IPSECKEY));
|
||||||
|
assert!(validate_record_parsing(Record::KEY));
|
||||||
|
assert!(validate_record_parsing(Record::KX));
|
||||||
|
assert!(validate_record_parsing(Record::LOC));
|
||||||
|
assert!(validate_record_parsing(Record::MX));
|
||||||
|
assert!(validate_record_parsing(Record::NAPTR));
|
||||||
|
assert!(validate_record_parsing(Record::NS));
|
||||||
|
assert!(validate_record_parsing(Record::NSEC));
|
||||||
|
assert!(validate_record_parsing(Record::NSEC3));
|
||||||
|
assert!(validate_record_parsing(Record::NSEC3PARAM));
|
||||||
|
assert!(validate_record_parsing(Record::OPENPGPKEY));
|
||||||
assert!(validate_record_parsing(Record::PTR));
|
assert!(validate_record_parsing(Record::PTR));
|
||||||
|
assert!(validate_record_parsing(Record::RRSIG));
|
||||||
|
assert!(validate_record_parsing(Record::RP));
|
||||||
|
assert!(validate_record_parsing(Record::SIG));
|
||||||
|
assert!(validate_record_parsing(Record::SOA));
|
||||||
|
assert!(validate_record_parsing(Record::SRV));
|
||||||
|
assert!(validate_record_parsing(Record::SSHFP));
|
||||||
|
assert!(validate_record_parsing(Record::TA));
|
||||||
|
assert!(validate_record_parsing(Record::TKEY));
|
||||||
|
assert!(validate_record_parsing(Record::TLSA));
|
||||||
|
assert!(validate_record_parsing(Record::TSIG));
|
||||||
assert!(validate_record_parsing(Record::TXT));
|
assert!(validate_record_parsing(Record::TXT));
|
||||||
|
assert!(validate_record_parsing(Record::URI));
|
||||||
|
assert!(validate_record_parsing(Record::ALIAS));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_record_parsing(record: Record) -> bool {
|
fn validate_record_parsing(record: Record) -> bool {
|
||||||
|
Loading…
Reference in New Issue
Block a user