about summary refs log tree commit diff
path: root/kittybox-rs/indieauth/src/pkce.rs
diff options
context:
space:
mode:
authorVika <vika@fireburn.ru>2023-07-29 21:59:56 +0300
committerVika <vika@fireburn.ru>2023-07-29 21:59:56 +0300
commit0617663b249f9ca488e5de652108b17d67fbaf45 (patch)
tree11564b6c8fa37bf9203a0a4cc1c4e9cc088cb1a5 /kittybox-rs/indieauth/src/pkce.rs
parent26c2b79f6a6380ae3224e9309b9f3352f5717bd7 (diff)
Moved the entire Kittybox tree into the root
Diffstat (limited to 'kittybox-rs/indieauth/src/pkce.rs')
-rw-r--r--kittybox-rs/indieauth/src/pkce.rs132
1 files changed, 0 insertions, 132 deletions
diff --git a/kittybox-rs/indieauth/src/pkce.rs b/kittybox-rs/indieauth/src/pkce.rs
deleted file mode 100644
index bf8d1a0..0000000
--- a/kittybox-rs/indieauth/src/pkce.rs
+++ /dev/null
@@ -1,132 +0,0 @@
-use serde::{Serialize, Deserialize};
-use rand::{Rng, distributions::Alphanumeric};
-use sha2::{Sha256, Digest};
-use data_encoding::BASE64URL;
-
-/// Methods to use for PKCE challenges.
-#[derive(PartialEq, Eq, Copy, Clone, Debug, Serialize, Deserialize, /*Default*/)]
-pub enum PKCEMethod {
-    /// Base64-encoded SHA256 hash of an ASCII string.
-    //#[default]
-    S256,
-    /// Plain string by itself. Please don't use this.
-    #[serde(rename = "snake_case")]
-    Plain
-}
-// manual impl until Rust 1.62 hits nixos-unstable
-impl Default for PKCEMethod {
-    fn default() -> Self { PKCEMethod::S256 }
-}
-impl PKCEMethod {
-    /// Return a string representing a PKCE method as it would be serialized.
-    pub fn as_str(&self) -> &'static str {
-        match self {
-            PKCEMethod::S256 => "S256",
-            PKCEMethod::Plain => "plain"
-        }
-    }
-}
-/// A PKCE verifier string that should be kept in secret until the end
-/// of the authentication ceremony, where it is revealed to prove that
-/// the one who uses the grant is the same entity who it was given to.
-#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
-pub struct PKCEVerifier(pub(super) String);
-
-impl AsRef<str> for PKCEVerifier {
-    fn as_ref(&self) -> &str {
-        self.0.as_str()
-    }
-}
-impl ToString for PKCEVerifier {
-    fn to_string(&self) -> String {
-        self.0.clone()
-    }
-}
-
-impl PKCEVerifier {
-    /// Generate a new PKCE verifier string of 128 bytes in length.
-    #[allow(clippy::new_without_default)]
-    pub fn new() -> Self {
-        let bytes = rand::thread_rng()
-            .sample_iter(&Alphanumeric)
-            .take(128)
-            .collect::<Vec<u8>>();
-        Self(String::from_utf8(bytes).unwrap())
-    }
-}
-
-/// A PKCE challenge as described in [RFC7636].
-///
-/// [RFC7636]: https://tools.ietf.org/html/rfc7636
-#[derive(Eq, PartialEq, Debug, Clone, Serialize, Deserialize)]
-pub struct PKCEChallenge {
-    code_challenge: String,
-    #[serde(rename = "code_challenge_method")]
-    method: PKCEMethod
-}
-
-impl PKCEChallenge {
-    /// Create a new challenge from a [PKCEVerifier] using a certain
-    /// [PKCEMethod].
-    pub fn new(code_verifier: &PKCEVerifier, method: PKCEMethod) -> Self {
-        Self {
-            code_challenge: match method {
-                PKCEMethod::S256 => {
-                    let mut hasher = Sha256::new();
-                    hasher.update(code_verifier.as_ref());
-                    let mut challenge = BASE64URL.encode(&hasher.finalize());
-                    challenge.retain(|c| c != '=');
-
-                    challenge
-                },
-                PKCEMethod::Plain => code_verifier.to_string(),
-            },
-            method
-        }
-    }
-
-    /// Verify that the [PKCEVerifier] corresponds to this challenge,
-    /// by creating a second challenge string and comparing it against
-    /// this challenge data.
-    ///
-    /// ```rust
-    /// use kittybox_indieauth::{PKCEVerifier, PKCEMethod, PKCEChallenge};
-    ///
-    /// let verifier = PKCEVerifier::new();
-    /// let challenge = PKCEChallenge::new(&verifier, PKCEMethod::default());
-    /// // Meanwhile, at the token endpoint, in the end of the ceremony...
-    /// // ...the challenge gets retrieved from the stored data and verified
-    /// assert!(challenge.verify(verifier))
-    /// ```
-    #[must_use]
-    pub fn verify(&self, code_verifier: PKCEVerifier) -> bool {
-        Self::new(&code_verifier, self.method) == *self
-    }
-
-    /// Return a reference to the code challenge string.
-    pub fn as_str(&self) -> &str {
-        self.code_challenge.as_str()
-    }
-
-    /// Return the method used to create this challenge.
-    pub fn method(&self) -> PKCEMethod {
-        self.method
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::{PKCEMethod, PKCEVerifier, PKCEChallenge};
-
-    #[test]
-    /// A snapshot test generated using [Aaron Parecki's PKCE
-    /// tools](https://example-app.com/pkce) that checks for a
-    /// conforming challenge.
-    fn test_pkce_challenge_verification() {
-        let verifier = PKCEVerifier("ec03310e4e90f7bc988af05384060c3c1afeae4bb4d0f648c5c06b63".to_owned());
-
-        let challenge = PKCEChallenge::new(&verifier, PKCEMethod::S256);
-
-        assert_eq!(challenge.as_str(), "aB8OG20Rh8UoQ9gFhI0YvPkx4dDW2MBspBKGXL6j6Wg");
-    }
-}