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 pub fn from_str(s: &str) -> Result<Self> {
46 match s.to_lowercase().as_str() {
47 "same-origin" => Ok(Self::SameOrigin),
48 "same-origin-allow-popups" => Ok(Self::SameOriginAllowPopups),
49 "unsafe-none" => Ok(Self::UnsafeNone),
50 _ => Err(Error::InvalidCoop(format!(
51 "Unknown Cross-Origin-Opener-Policy: '{}'",
52 s
53 ))),
54 }
55 }
56}
57
58impl std::fmt::Display for CrossOriginOpenerPolicy {
59 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60 write!(f, "{}", self.as_str())
61 }
62}
63
64#[derive(Debug, Clone, Copy, PartialEq, Eq)]
78pub enum CrossOriginEmbedderPolicy {
79 UnsafeNone,
82 RequireCorp,
85 Credentialless,
88}
89
90impl CrossOriginEmbedderPolicy {
91 pub fn as_str(&self) -> &'static str {
93 match self {
94 Self::UnsafeNone => "unsafe-none",
95 Self::RequireCorp => "require-corp",
96 Self::Credentialless => "credentialless",
97 }
98 }
99
100 pub fn from_str(s: &str) -> Result<Self> {
102 match s.to_lowercase().as_str() {
103 "unsafe-none" => Ok(Self::UnsafeNone),
104 "require-corp" => Ok(Self::RequireCorp),
105 "credentialless" => Ok(Self::Credentialless),
106 _ => Err(Error::InvalidCoep(format!(
107 "Unknown Cross-Origin-Embedder-Policy: '{}'",
108 s
109 ))),
110 }
111 }
112}
113
114impl std::fmt::Display for CrossOriginEmbedderPolicy {
115 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
116 write!(f, "{}", self.as_str())
117 }
118}
119
120#[derive(Debug, Clone, Copy, PartialEq, Eq)]
134pub enum CrossOriginResourcePolicy {
135 SameOrigin,
137 SameSite,
139 CrossOrigin,
141}
142
143impl CrossOriginResourcePolicy {
144 pub fn as_str(&self) -> &'static str {
146 match self {
147 Self::SameOrigin => "same-origin",
148 Self::SameSite => "same-site",
149 Self::CrossOrigin => "cross-origin",
150 }
151 }
152
153 pub fn from_str(s: &str) -> Result<Self> {
155 match s.to_lowercase().as_str() {
156 "same-origin" => Ok(Self::SameOrigin),
157 "same-site" => Ok(Self::SameSite),
158 "cross-origin" => Ok(Self::CrossOrigin),
159 _ => Err(Error::InvalidCorp(format!(
160 "Unknown Cross-Origin-Resource-Policy: '{}'",
161 s
162 ))),
163 }
164 }
165}
166
167impl std::fmt::Display for CrossOriginResourcePolicy {
168 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
169 write!(f, "{}", self.as_str())
170 }
171}
172
173#[cfg(test)]
174mod tests {
175 use super::*;
176
177 #[test]
179 fn test_coop_as_str() {
180 assert_eq!(CrossOriginOpenerPolicy::SameOrigin.as_str(), "same-origin");
181 assert_eq!(
182 CrossOriginOpenerPolicy::SameOriginAllowPopups.as_str(),
183 "same-origin-allow-popups"
184 );
185 assert_eq!(CrossOriginOpenerPolicy::UnsafeNone.as_str(), "unsafe-none");
186 }
187
188 #[test]
189 fn test_coop_from_str() {
190 assert_eq!(
191 CrossOriginOpenerPolicy::from_str("same-origin").unwrap(),
192 CrossOriginOpenerPolicy::SameOrigin
193 );
194 assert_eq!(
195 CrossOriginOpenerPolicy::from_str("same-origin-allow-popups").unwrap(),
196 CrossOriginOpenerPolicy::SameOriginAllowPopups
197 );
198 assert_eq!(
199 CrossOriginOpenerPolicy::from_str("unsafe-none").unwrap(),
200 CrossOriginOpenerPolicy::UnsafeNone
201 );
202 assert!(CrossOriginOpenerPolicy::from_str("invalid").is_err());
203 }
204
205 #[test]
207 fn test_coep_as_str() {
208 assert_eq!(
209 CrossOriginEmbedderPolicy::UnsafeNone.as_str(),
210 "unsafe-none"
211 );
212 assert_eq!(
213 CrossOriginEmbedderPolicy::RequireCorp.as_str(),
214 "require-corp"
215 );
216 assert_eq!(
217 CrossOriginEmbedderPolicy::Credentialless.as_str(),
218 "credentialless"
219 );
220 }
221
222 #[test]
223 fn test_coep_from_str() {
224 assert_eq!(
225 CrossOriginEmbedderPolicy::from_str("unsafe-none").unwrap(),
226 CrossOriginEmbedderPolicy::UnsafeNone
227 );
228 assert_eq!(
229 CrossOriginEmbedderPolicy::from_str("require-corp").unwrap(),
230 CrossOriginEmbedderPolicy::RequireCorp
231 );
232 assert_eq!(
233 CrossOriginEmbedderPolicy::from_str("credentialless").unwrap(),
234 CrossOriginEmbedderPolicy::Credentialless
235 );
236 assert!(CrossOriginEmbedderPolicy::from_str("invalid").is_err());
237 }
238
239 #[test]
241 fn test_corp_as_str() {
242 assert_eq!(
243 CrossOriginResourcePolicy::SameOrigin.as_str(),
244 "same-origin"
245 );
246 assert_eq!(CrossOriginResourcePolicy::SameSite.as_str(), "same-site");
247 assert_eq!(
248 CrossOriginResourcePolicy::CrossOrigin.as_str(),
249 "cross-origin"
250 );
251 }
252
253 #[test]
254 fn test_corp_from_str() {
255 assert_eq!(
256 CrossOriginResourcePolicy::from_str("same-origin").unwrap(),
257 CrossOriginResourcePolicy::SameOrigin
258 );
259 assert_eq!(
260 CrossOriginResourcePolicy::from_str("same-site").unwrap(),
261 CrossOriginResourcePolicy::SameSite
262 );
263 assert_eq!(
264 CrossOriginResourcePolicy::from_str("cross-origin").unwrap(),
265 CrossOriginResourcePolicy::CrossOrigin
266 );
267 assert!(CrossOriginResourcePolicy::from_str("invalid").is_err());
268 }
269
270 #[test]
271 fn test_display() {
272 assert_eq!(
273 CrossOriginOpenerPolicy::SameOrigin.to_string(),
274 "same-origin"
275 );
276 assert_eq!(
277 CrossOriginEmbedderPolicy::RequireCorp.to_string(),
278 "require-corp"
279 );
280 assert_eq!(
281 CrossOriginResourcePolicy::SameSite.to_string(),
282 "same-site"
283 );
284 }
285}