1use crate::{httpdata::HttpData, media_types::RDAP_MEDIA_TYPE, response::types::ExtensionId};
2
3use super::{Check, Checks, GetChecks};
4
5impl GetChecks for HttpData {
6 fn get_checks(&self, params: crate::check::CheckParams) -> crate::check::Checks {
7 let mut items = vec![];
8
9 if let Some(allow_origin) = &self.access_control_allow_origin {
11 if !allow_origin.eq("*") {
12 items.push(Check::CorsAllowOriginStarRecommended.check_item())
13 }
14 } else {
15 items.push(Check::CorsAllowOriginRecommended.check_item())
16 }
17 if self.access_control_allow_credentials.is_some() {
18 items.push(Check::CorsAllowCredentialsNotRecommended.check_item())
19 }
20 if let Some(content_type) = &self.content_type {
21 if !content_type.starts_with(RDAP_MEDIA_TYPE) {
22 items.push(Check::ContentTypeIsNotRdap.check_item());
23 }
24 } else {
25 items.push(Check::ContentTypeIsAbsent.check_item());
26 }
27
28 if params
30 .root
31 .has_extension_id(ExtensionId::IcannRdapTechnicalImplementationGuide0)
32 || params
33 .root
34 .has_extension_id(ExtensionId::IcannRdapTechnicalImplementationGuide1)
35 {
36 if let Some(scheme) = &self.scheme {
37 if !scheme.eq_ignore_ascii_case("HTTPS") {
38 items.push(Check::MustUseHttps.check_item());
39 }
40 } else {
41 items.push(Check::MustUseHttps.check_item());
42 }
43 if let Some(allow_origin) = &self.access_control_allow_origin {
44 if !allow_origin.eq("*") {
45 items.push(Check::AllowOriginNotStar.check_item())
46 }
47 } else {
48 items.push(Check::AllowOriginNotStar.check_item())
49 }
50 }
51
52 Checks {
53 rdap_struct: super::RdapStructure::HttpData,
54 items,
55 sub_checks: vec![],
56 }
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use crate::{
63 check::{Check, CheckParams, GetChecks},
64 httpdata::HttpData,
65 media_types::{JSON_MEDIA_TYPE, RDAP_MEDIA_TYPE},
66 prelude::{Common, ObjectCommon, ToResponse},
67 response::{domain::Domain, types::ExtensionId},
68 };
69
70 #[test]
71 fn check_not_rdap_media() {
72 let domain = Domain {
74 common: Common::level0()
75 .extension(ExtensionId::IcannRdapTechnicalImplementationGuide0.to_extension())
76 .build(),
77 object_common: ObjectCommon::domain().build(),
78 ldh_name: Some("foo.example".to_string()),
79 unicode_name: None,
80 variants: None,
81 secure_dns: None,
82 nameservers: None,
83 public_ids: None,
84 network: None,
85 };
86 let rdap = domain.to_response();
87
88 let http_data = HttpData::example().content_type(JSON_MEDIA_TYPE).build();
90
91 let checks = http_data.get_checks(CheckParams::for_rdap(&rdap));
93
94 assert!(checks
96 .items
97 .iter()
98 .any(|c| c.check == Check::ContentTypeIsNotRdap));
99 }
100
101 #[test]
102 fn check_exactly_rdap_media() {
103 let domain = Domain {
105 common: Common::level0()
106 .extension(ExtensionId::IcannRdapTechnicalImplementationGuide0.to_extension())
107 .build(),
108 object_common: ObjectCommon::domain().build(),
109 ldh_name: Some("foo.example".to_string()),
110 unicode_name: None,
111 variants: None,
112 secure_dns: None,
113 nameservers: None,
114 public_ids: None,
115 network: None,
116 };
117 let rdap = domain.to_response();
118
119 let http_data = HttpData::example().content_type(RDAP_MEDIA_TYPE).build();
121
122 let checks = http_data.get_checks(CheckParams::for_rdap(&rdap));
124
125 assert!(!checks
127 .items
128 .iter()
129 .any(|c| c.check == Check::ContentTypeIsNotRdap));
130 }
131
132 #[test]
133 fn check_rdap_media_with_charset_parameter() {
134 let domain = Domain {
136 common: Common::level0()
137 .extension(ExtensionId::IcannRdapTechnicalImplementationGuide0.to_extension())
138 .build(),
139 object_common: ObjectCommon::domain().build(),
140 ldh_name: Some("foo.example".to_string()),
141 unicode_name: None,
142 variants: None,
143 secure_dns: None,
144 nameservers: None,
145 public_ids: None,
146 network: None,
147 };
148 let rdap = domain.to_response();
149
150 let mt = format!("{RDAP_MEDIA_TYPE};charset=UTF-8");
152 let http_data = HttpData::example().content_type(mt).build();
153
154 let checks = http_data.get_checks(CheckParams::for_rdap(&rdap));
156
157 assert!(!checks
159 .items
160 .iter()
161 .any(|c| c.check == Check::ContentTypeIsNotRdap));
162 }
163
164 #[test]
165 fn check_media_type_absent() {
166 let domain = Domain {
168 common: Common::level0()
169 .extension(ExtensionId::IcannRdapTechnicalImplementationGuide0.to_extension())
170 .build(),
171 object_common: ObjectCommon::domain().build(),
172 ldh_name: Some("foo.example".to_string()),
173 unicode_name: None,
174 variants: None,
175 secure_dns: None,
176 nameservers: None,
177 public_ids: None,
178 network: None,
179 };
180 let rdap = domain.to_response();
181
182 let http_data = HttpData::example().build();
184
185 let checks = http_data.get_checks(CheckParams::for_rdap(&rdap));
187
188 assert!(checks
190 .items
191 .iter()
192 .any(|c| c.check == Check::ContentTypeIsAbsent));
193 }
194
195 #[test]
196 fn check_cors_header_with_tig() {
197 let domain = Domain {
199 common: Common::level0()
200 .extension(ExtensionId::IcannRdapTechnicalImplementationGuide0.to_extension())
201 .build(),
202 object_common: ObjectCommon::domain().build(),
203 ldh_name: Some("foo.example".to_string()),
204 unicode_name: None,
205 variants: None,
206 secure_dns: None,
207 nameservers: None,
208 public_ids: None,
209 network: None,
210 };
211 let rdap = domain.to_response();
212
213 let http_data = HttpData::example().access_control_allow_origin("*").build();
215
216 let checks = http_data.get_checks(CheckParams::for_rdap(&rdap));
218
219 assert!(!checks
221 .items
222 .iter()
223 .any(|c| c.check == Check::AllowOriginNotStar));
224 }
225
226 #[test]
227 fn check_cors_header_with_foo_and_tig() {
228 let domain = Domain {
230 common: Common::level0()
231 .extension(ExtensionId::IcannRdapTechnicalImplementationGuide0.to_extension())
232 .build(),
233 object_common: ObjectCommon::domain().build(),
234 ldh_name: Some("foo.example".to_string()),
235 unicode_name: None,
236 variants: None,
237 secure_dns: None,
238 nameservers: None,
239 public_ids: None,
240 network: None,
241 };
242 let rdap = domain.to_response();
243
244 let http_data = HttpData::example()
246 .access_control_allow_origin("foo")
247 .build();
248
249 let checks = http_data.get_checks(CheckParams::for_rdap(&rdap));
251
252 assert!(checks
254 .items
255 .iter()
256 .any(|c| c.check == Check::AllowOriginNotStar));
257 }
258
259 #[test]
260 fn check_no_cors_header_and_tig() {
261 let domain = Domain {
263 common: Common::level0()
264 .extension(ExtensionId::IcannRdapTechnicalImplementationGuide0.to_extension())
265 .build(),
266 object_common: ObjectCommon::domain().build(),
267 ldh_name: Some("foo.example".to_string()),
268 unicode_name: None,
269 variants: None,
270 secure_dns: None,
271 nameservers: None,
272 public_ids: None,
273 network: None,
274 };
275 let rdap = domain.to_response();
276
277 let http_data = HttpData::example().build();
279
280 let checks = http_data.get_checks(CheckParams::for_rdap(&rdap));
282
283 dbg!(&checks);
285 assert!(checks
286 .items
287 .iter()
288 .any(|c| c.check == Check::AllowOriginNotStar));
289 }
290
291 #[test]
292 fn given_response_is_over_https_and_tig() {
293 let domain = Domain {
295 common: Common::level0()
296 .extension(ExtensionId::IcannRdapTechnicalImplementationGuide0.to_extension())
297 .build(),
298 object_common: ObjectCommon::domain().build(),
299 ldh_name: Some("foo.example".to_string()),
300 unicode_name: None,
301 variants: None,
302 secure_dns: None,
303 nameservers: None,
304 public_ids: None,
305 network: None,
306 };
307 let rdap = domain.to_response();
308
309 let http_data = HttpData::now().scheme("https").host("example.com").build();
311
312 let checks = http_data.get_checks(CheckParams::for_rdap(&rdap));
314
315 assert!(!checks.items.iter().any(|c| c.check == Check::MustUseHttps));
317 }
318
319 #[test]
320 fn response_over_htttp_and_tig() {
321 let domain = Domain {
323 common: Common::level0()
324 .extension(ExtensionId::IcannRdapTechnicalImplementationGuide0.to_extension())
325 .build(),
326 object_common: ObjectCommon::domain().build(),
327 ldh_name: Some("foo.example".to_string()),
328 unicode_name: None,
329 variants: None,
330 secure_dns: None,
331 nameservers: None,
332 public_ids: None,
333 network: None,
334 };
335 let rdap = domain.to_response();
336
337 let http_data = HttpData::now().scheme("http").host("example.com").build();
339
340 let checks = http_data.get_checks(CheckParams::for_rdap(&rdap));
342
343 assert!(checks.items.iter().any(|c| c.check == Check::MustUseHttps));
345 }
346}