serde feature and support
This commit is contained in:
parent
3db326a40f
commit
8e97870352
56
Cargo.lock
generated
56
Cargo.lock
generated
|
@ -68,6 +68,44 @@ version = "0.2.159"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.210"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.210"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.8"
|
||||
|
@ -84,15 +122,33 @@ name = "subresource_integrity"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"serde",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
|
|
|
@ -5,7 +5,9 @@ edition = "2021"
|
|||
|
||||
[features]
|
||||
default = []
|
||||
serde = ["dep:serde"]
|
||||
|
||||
[dependencies]
|
||||
base64 = "0.22.1"
|
||||
serde = { version = "1.0.210", features = ["derive"], optional = true }
|
||||
sha2 = "0.10.8"
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#[cfg(feature = "serde")]
|
||||
pub mod serialization;
|
||||
|
||||
use core::fmt;
|
||||
|
||||
use base64::{prelude::BASE64_STANDARD, Engine};
|
||||
|
@ -11,6 +14,7 @@ pub enum Error {
|
|||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub enum Algorithm {
|
||||
SHA256,
|
||||
SHA384,
|
||||
|
@ -102,7 +106,6 @@ impl TryFrom<&str> for Integrity {
|
|||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
let (algo, hash) = Self::split(value)?;
|
||||
println!("{algo} {hash}");
|
||||
Self::from_base64(Algorithm::try_from(algo)?, hash)
|
||||
}
|
||||
}
|
||||
|
|
73
src/serialization.rs
Normal file
73
src/serialization.rs
Normal file
|
@ -0,0 +1,73 @@
|
|||
use serde::Serialize;
|
||||
|
||||
use crate::Integrity;
|
||||
|
||||
impl Serialize for Integrity {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_str(self.to_string().as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::Deserialize<'de> for Integrity {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_string(IntegrityVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
struct IntegrityVisitor;
|
||||
impl<'de> serde::de::Visitor<'de> for IntegrityVisitor {
|
||||
type Value = Integrity;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("a string with the format of <hash-algo>-<base64-hash>")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
Integrity::try_from(v).map_err(|_| E::custom("invalid sri"))
|
||||
}
|
||||
|
||||
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
Integrity::try_from(v).map_err(|_| E::custom("invalid sri"))
|
||||
}
|
||||
|
||||
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
Integrity::try_from(v).map_err(|_| E::custom("invalid sri"))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde::{
|
||||
de::{
|
||||
value::{Error as ValueError, StrDeserializer},
|
||||
IntoDeserializer,
|
||||
},
|
||||
Deserialize,
|
||||
};
|
||||
|
||||
use crate::Integrity;
|
||||
|
||||
#[test]
|
||||
fn serde_deserialization() {
|
||||
let de: StrDeserializer<ValueError> =
|
||||
"sha384-H8BRh8j48O9oYatfu5AZzq6A9RINhZO5H16dQZngK7T62em8MUt1FLm52t+eX6xO"
|
||||
.into_deserializer();
|
||||
let result = Integrity::deserialize(de).unwrap();
|
||||
assert!(result.verify("alert(\'Hello, world.\');"));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue