http_security_headers/policy/
cross_origin.rs1use crate::error::{Error, Result};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub enum CrossOriginOpenerPolicy {
23 SameOrigin,
25 SameOriginAllowPopups,
28 UnsafeNone,
32}
33
34impl CrossOriginOpenerPolicy {
35 pub fn as_str(&self) -> &'static str {
37 match self {
38 Self::SameOrigin => "same-origin",
39 Self::SameOriginAllowPopups => "same-origin-allow-popups",
40 Self::UnsafeNone => "unsafe-none",
41 }
42 }
43}
44
45impl std::str::FromStr for CrossOriginOpenerPolicy {
46 type Err = Error;
47
48 fn from_str(s: &str) -> Result<Self> {
49 match s.to_lowercase().as_str() {
50 "same-origin" => Ok(Self::SameOrigin),
51 "same-origin-allow-popups" => Ok(Self::SameOriginAllowPopups),
52 "unsafe-none" => Ok(Self::UnsafeNone),
53 _ => Err(Error::InvalidCoop(format!(
54 "Unknown Cross-Origin-Opener-Policy: '{}'",
55 s
56 ))),
57 }
58 }
59}
60
61impl std::fmt::Display for CrossOriginOpenerPolicy {
62 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63 write!(f, "{}", self.as_str())
64 }
65}
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq)]
81pub enum CrossOriginEmbedderPolicy {
82 UnsafeNone,
85 RequireCorp,
88 Credentialless,
91}
92
93impl CrossOriginEmbedderPolicy {
94 pub fn as_str(&self) -> &'static str {
96 match self {
97 Self::UnsafeNone => "unsafe-none",
98 Self::RequireCorp => "require-corp",
99 Self::Credentialless => "credentialless",
100 }
101 }
102}
103
104impl std::str::FromStr for CrossOriginEmbedderPolicy {
105 type Err = Error;
106
107 fn from_str(s: &str) -> Result<Self> {
108 match s.to_lowercase().as_str() {
109 "unsafe-none" => Ok(Self::UnsafeNone),
110 "require-corp" => Ok(Self::RequireCorp),
111 "credentialless" => Ok(Self::Credentialless),
112 _ => Err(Error::InvalidCoep(format!(
113 "Unknown Cross-Origin-Embedder-Policy: '{}'",
114 s
115 ))),
116 }
117 }
118}
119
120impl std::fmt::Display for CrossOriginEmbedderPolicy {
121 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
122 write!(f, "{}", self.as_str())
123 }
124}
125
126#[derive(Debug, Clone, Copy, PartialEq, Eq)]
140pub enum CrossOriginResourcePolicy {
141 SameOrigin,
143 SameSite,
145 CrossOrigin,
147}
148
149impl CrossOriginResourcePolicy {
150 pub fn as_str(&self) -> &'static str {
152 match self {
153 Self::SameOrigin => "same-origin",
154 Self::SameSite => "same-site",
155 Self::CrossOrigin => "cross-origin",
156 }
157 }
158}
159
160impl std::str::FromStr for CrossOriginResourcePolicy {
161 type Err = Error;
162
163 fn from_str(s: &str) -> Result<Self> {
164 match s.to_lowercase().as_str() {
165 "same-origin" => Ok(Self::SameOrigin),
166 "same-site" => Ok(Self::SameSite),
167 "cross-origin" => Ok(Self::CrossOrigin),
168 _ => Err(Error::InvalidCorp(format!(
169 "Unknown Cross-Origin-Resource-Policy: '{}'",
170 s
171 ))),
172 }
173 }
174}
175
176impl std::fmt::Display for CrossOriginResourcePolicy {
177 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
178 write!(f, "{}", self.as_str())
179 }
180}
181
182#[cfg(test)]
183mod tests {
184 use super::*;
185 use std::str::FromStr;
186
187 #[test]
189 fn test_coop_as_str() {
190 assert_eq!(CrossOriginOpenerPolicy::SameOrigin.as_str(), "same-origin");
191 assert_eq!(
192 CrossOriginOpenerPolicy::SameOriginAllowPopups.as_str(),
193 "same-origin-allow-popups"
194 );
195 assert_eq!(CrossOriginOpenerPolicy::UnsafeNone.as_str(), "unsafe-none");
196 }
197
198 #[test]
199 fn test_coop_from_str() {
200 assert_eq!(
201 CrossOriginOpenerPolicy::from_str("same-origin").unwrap(),
202 CrossOriginOpenerPolicy::SameOrigin
203 );
204 assert_eq!(
205 CrossOriginOpenerPolicy::from_str("same-origin-allow-popups").unwrap(),
206 CrossOriginOpenerPolicy::SameOriginAllowPopups
207 );
208 assert_eq!(
209 CrossOriginOpenerPolicy::from_str("unsafe-none").unwrap(),
210 CrossOriginOpenerPolicy::UnsafeNone
211 );
212 assert!(CrossOriginOpenerPolicy::from_str("invalid").is_err());
213 }
214
215 #[test]
217 fn test_coep_as_str() {
218 assert_eq!(
219 CrossOriginEmbedderPolicy::UnsafeNone.as_str(),
220 "unsafe-none"
221 );
222 assert_eq!(
223 CrossOriginEmbedderPolicy::RequireCorp.as_str(),
224 "require-corp"
225 );
226 assert_eq!(
227 CrossOriginEmbedderPolicy::Credentialless.as_str(),
228 "credentialless"
229 );
230 }
231
232 #[test]
233 fn test_coep_from_str() {
234 assert_eq!(
235 CrossOriginEmbedderPolicy::from_str("unsafe-none").unwrap(),
236 CrossOriginEmbedderPolicy::UnsafeNone
237 );
238 assert_eq!(
239 CrossOriginEmbedderPolicy::from_str("require-corp").unwrap(),
240 CrossOriginEmbedderPolicy::RequireCorp
241 );
242 assert_eq!(
243 CrossOriginEmbedderPolicy::from_str("credentialless").unwrap(),
244 CrossOriginEmbedderPolicy::Credentialless
245 );
246 assert!(CrossOriginEmbedderPolicy::from_str("invalid").is_err());
247 }
248
249 #[test]
251 fn test_corp_as_str() {
252 assert_eq!(
253 CrossOriginResourcePolicy::SameOrigin.as_str(),
254 "same-origin"
255 );
256 assert_eq!(CrossOriginResourcePolicy::SameSite.as_str(), "same-site");
257 assert_eq!(
258 CrossOriginResourcePolicy::CrossOrigin.as_str(),
259 "cross-origin"
260 );
261 }
262
263 #[test]
264 fn test_corp_from_str() {
265 assert_eq!(
266 CrossOriginResourcePolicy::from_str("same-origin").unwrap(),
267 CrossOriginResourcePolicy::SameOrigin
268 );
269 assert_eq!(
270 CrossOriginResourcePolicy::from_str("same-site").unwrap(),
271 CrossOriginResourcePolicy::SameSite
272 );
273 assert_eq!(
274 CrossOriginResourcePolicy::from_str("cross-origin").unwrap(),
275 CrossOriginResourcePolicy::CrossOrigin
276 );
277 assert!(CrossOriginResourcePolicy::from_str("invalid").is_err());
278 }
279
280 #[test]
281 fn test_display() {
282 assert_eq!(
283 CrossOriginOpenerPolicy::SameOrigin.to_string(),
284 "same-origin"
285 );
286 assert_eq!(
287 CrossOriginEmbedderPolicy::RequireCorp.to_string(),
288 "require-corp"
289 );
290 assert_eq!(
291 CrossOriginResourcePolicy::SameSite.to_string(),
292 "same-site"
293 );
294 }
295}