about summary refs log tree commit diff
path: root/kittybox-rs/indieauth/src/pkce.rs
diff options
context:
space:
mode:
Diffstat (limited to 'kittybox-rs/indieauth/src/pkce.rs')
-rw-r--r--kittybox-rs/indieauth/src/pkce.rs50
1 files changed, 33 insertions, 17 deletions
diff --git a/kittybox-rs/indieauth/src/pkce.rs b/kittybox-rs/indieauth/src/pkce.rs
index 6dabcc3..249917e 100644
--- a/kittybox-rs/indieauth/src/pkce.rs
+++ b/kittybox-rs/indieauth/src/pkce.rs
@@ -3,12 +3,22 @@ use rand::{Rng, distributions::Alphanumeric};
 use sha2::{Sha256, Digest};
 use data_encoding::BASE64URL;
 
-#[derive(PartialEq, Eq, Copy, Clone, Debug, Serialize, Deserialize)]
+/// 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.
     Plain
 }
-
+// manual impl until Rust 1.62 hits nixos-unstable
+impl Default for PKCEMethod {
+    fn default() -> Self { PKCEMethod::S256 }
+}
+/// 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);
 
@@ -24,7 +34,9 @@ impl ToString for PKCEVerifier {
 }
 
 impl PKCEVerifier {
-    fn new() -> Self {
+    /// 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)
@@ -33,6 +45,9 @@ impl PKCEVerifier {
     }
 }
 
+/// 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,
@@ -40,6 +55,8 @@ pub struct PKCEChallenge {
 }
 
 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 {
@@ -54,22 +71,21 @@ impl PKCEChallenge {
         }
     }
 
+    /// 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.clone(), 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
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn test_pkce() {
-        let verifier = PKCEVerifier::new();
-        let challenge = PKCEChallenge::new(verifier.clone(), PKCEMethod::S256);
-
-        assert!(challenge.verify(verifier));
-    }
-
-}