use crate::{httpdata::HttpData, media_types::RDAP_MEDIA_TYPE, prelude::ExtensionId};
use super::{Check, Checks, GetChecks};
impl GetChecks for HttpData {
fn get_checks(
&self,
index: Option<usize>,
params: crate::check::CheckParams,
) -> crate::check::Checks {
let mut items = vec![];
if let Some(allow_origin) = &self.access_control_allow_origin {
if !allow_origin.eq("*") {
items.push(Check::CorsAllowOriginStarRecommended.check_item())
}
} else {
items.push(Check::CorsAllowOriginRecommended.check_item())
}
if self.access_control_allow_credentials.is_some() {
items.push(Check::CorsAllowCredentialsNotRecommended.check_item())
}
if let Some(content_type) = &self.content_type {
if !content_type.starts_with(RDAP_MEDIA_TYPE) {
items.push(Check::ContentTypeIsNotRdap.check_item());
}
} else {
items.push(Check::ContentTypeIsAbsent.check_item());
}
if params
.root
.has_extension_id(ExtensionId::IcannRdapTechnicalImplementationGuide0)
|| params
.root
.has_extension_id(ExtensionId::IcannRdapTechnicalImplementationGuide1)
{
if let Some(scheme) = &self.scheme {
if !scheme.eq_ignore_ascii_case("HTTPS") {
items.push(Check::MustUseHttps.check_item());
}
} else {
items.push(Check::MustUseHttps.check_item());
}
if let Some(allow_origin) = &self.access_control_allow_origin {
if !allow_origin.eq("*") {
items.push(Check::AllowOriginNotStar.check_item())
}
} else {
items.push(Check::AllowOriginNotStar.check_item())
}
}
Checks {
rdap_struct: super::RdapStructure::HttpData,
index,
items,
sub_checks: vec![],
}
}
}
#[cfg(test)]
mod tests {
use crate::{
check::{Check, CheckParams, GetChecks},
httpdata::HttpData,
media_types::{JSON_MEDIA_TYPE, RDAP_MEDIA_TYPE},
prelude::{Common, ExtensionId, ObjectCommon, ToResponse},
response::domain::Domain,
};
#[test]
fn check_not_rdap_media() {
let domain = Domain {
common: Common::level0()
.extension(ExtensionId::IcannRdapTechnicalImplementationGuide0.to_extension())
.build(),
object_common: ObjectCommon::domain().build(),
ldh_name: Some("foo.example".to_string()),
unicode_name: None,
variants: None,
secure_dns: None,
nameservers: None,
public_ids: None,
network: None,
ttl0_data: None,
};
let rdap = domain.to_response();
let http_data = HttpData::example().content_type(JSON_MEDIA_TYPE).build();
let checks = http_data.get_checks(None, CheckParams::for_rdap(&rdap));
assert!(checks
.items
.iter()
.any(|c| c.check == Check::ContentTypeIsNotRdap));
}
#[test]
fn check_exactly_rdap_media() {
let domain = Domain {
common: Common::level0()
.extension(ExtensionId::IcannRdapTechnicalImplementationGuide0.to_extension())
.build(),
object_common: ObjectCommon::domain().build(),
ldh_name: Some("foo.example".to_string()),
unicode_name: None,
variants: None,
secure_dns: None,
nameservers: None,
public_ids: None,
network: None,
ttl0_data: None,
};
let rdap = domain.to_response();
let http_data = HttpData::example().content_type(RDAP_MEDIA_TYPE).build();
let checks = http_data.get_checks(None, CheckParams::for_rdap(&rdap));
assert!(!checks
.items
.iter()
.any(|c| c.check == Check::ContentTypeIsNotRdap));
}
#[test]
fn check_rdap_media_with_charset_parameter() {
let domain = Domain {
common: Common::level0()
.extension(ExtensionId::IcannRdapTechnicalImplementationGuide0.to_extension())
.build(),
object_common: ObjectCommon::domain().build(),
ldh_name: Some("foo.example".to_string()),
unicode_name: None,
variants: None,
secure_dns: None,
nameservers: None,
public_ids: None,
network: None,
ttl0_data: None,
};
let rdap = domain.to_response();
let mt = format!("{RDAP_MEDIA_TYPE};charset=UTF-8");
let http_data = HttpData::example().content_type(mt).build();
let checks = http_data.get_checks(None, CheckParams::for_rdap(&rdap));
assert!(!checks
.items
.iter()
.any(|c| c.check == Check::ContentTypeIsNotRdap));
}
#[test]
fn check_media_type_absent() {
let domain = Domain {
common: Common::level0()
.extension(ExtensionId::IcannRdapTechnicalImplementationGuide0.to_extension())
.build(),
object_common: ObjectCommon::domain().build(),
ldh_name: Some("foo.example".to_string()),
unicode_name: None,
variants: None,
secure_dns: None,
nameservers: None,
public_ids: None,
network: None,
ttl0_data: None,
};
let rdap = domain.to_response();
let http_data = HttpData::example().build();
let checks = http_data.get_checks(None, CheckParams::for_rdap(&rdap));
assert!(checks
.items
.iter()
.any(|c| c.check == Check::ContentTypeIsAbsent));
}
#[test]
fn check_cors_header_with_tig() {
let domain = Domain {
common: Common::level0()
.extension(ExtensionId::IcannRdapTechnicalImplementationGuide0.to_extension())
.build(),
object_common: ObjectCommon::domain().build(),
ldh_name: Some("foo.example".to_string()),
unicode_name: None,
variants: None,
secure_dns: None,
nameservers: None,
public_ids: None,
network: None,
ttl0_data: None,
};
let rdap = domain.to_response();
let http_data = HttpData::example().access_control_allow_origin("*").build();
let checks = http_data.get_checks(None, CheckParams::for_rdap(&rdap));
assert!(!checks
.items
.iter()
.any(|c| c.check == Check::AllowOriginNotStar));
}
#[test]
fn check_cors_header_with_foo_and_tig() {
let domain = Domain {
common: Common::level0()
.extension(ExtensionId::IcannRdapTechnicalImplementationGuide0.to_extension())
.build(),
object_common: ObjectCommon::domain().build(),
ldh_name: Some("foo.example".to_string()),
unicode_name: None,
variants: None,
secure_dns: None,
nameservers: None,
public_ids: None,
network: None,
ttl0_data: None,
};
let rdap = domain.to_response();
let http_data = HttpData::example()
.access_control_allow_origin("foo")
.build();
let checks = http_data.get_checks(None, CheckParams::for_rdap(&rdap));
assert!(checks
.items
.iter()
.any(|c| c.check == Check::AllowOriginNotStar));
}
#[test]
fn check_no_cors_header_and_tig() {
let domain = Domain {
common: Common::level0()
.extension(ExtensionId::IcannRdapTechnicalImplementationGuide0.to_extension())
.build(),
object_common: ObjectCommon::domain().build(),
ldh_name: Some("foo.example".to_string()),
unicode_name: None,
variants: None,
secure_dns: None,
nameservers: None,
public_ids: None,
network: None,
ttl0_data: None,
};
let rdap = domain.to_response();
let http_data = HttpData::example().build();
let checks = http_data.get_checks(None, CheckParams::for_rdap(&rdap));
dbg!(&checks);
assert!(checks
.items
.iter()
.any(|c| c.check == Check::AllowOriginNotStar));
}
#[test]
fn given_response_is_over_https_and_tig() {
let domain = Domain {
common: Common::level0()
.extension(ExtensionId::IcannRdapTechnicalImplementationGuide0.to_extension())
.build(),
object_common: ObjectCommon::domain().build(),
ldh_name: Some("foo.example".to_string()),
unicode_name: None,
variants: None,
secure_dns: None,
nameservers: None,
public_ids: None,
network: None,
ttl0_data: None,
};
let rdap = domain.to_response();
let http_data = HttpData::now().scheme("https").host("example.com").build();
let checks = http_data.get_checks(None, CheckParams::for_rdap(&rdap));
assert!(!checks.items.iter().any(|c| c.check == Check::MustUseHttps));
}
#[test]
fn response_over_http_and_tig() {
let domain = Domain {
common: Common::level0()
.extension(ExtensionId::IcannRdapTechnicalImplementationGuide0.to_extension())
.build(),
object_common: ObjectCommon::domain().build(),
ldh_name: Some("foo.example".to_string()),
unicode_name: None,
variants: None,
secure_dns: None,
nameservers: None,
public_ids: None,
network: None,
ttl0_data: None,
};
let rdap = domain.to_response();
let http_data = HttpData::now().scheme("http").host("example.com").build();
let checks = http_data.get_checks(None, CheckParams::for_rdap(&rdap));
assert!(checks.items.iter().any(|c| c.check == Check::MustUseHttps));
}
}