Skip to content

Commit d7ee403

Browse files
committed
rebase
1 parent b6aaf74 commit d7ee403

File tree

3 files changed

+25
-116
lines changed

3 files changed

+25
-116
lines changed

cot/src/admin.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ use derive_more::Debug;
2121
use http::request::Parts;
2222
use serde::Deserialize;
2323

24-
use crate::auth::{Auth, Password};
24+
use crate::auth::Auth;
25+
use crate::form::types::Password;
2526
use crate::form::{
2627
Form, FormContext, FormErrorTarget, FormField, FormFieldValidationError, FormResult,
2728
};

cot/src/auth.rs

Lines changed: 7 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use std::any::Any;
1313
use std::borrow::Cow;
1414
use std::sync::{Arc, Mutex, MutexGuard};
1515

16+
/// backwards compatible shim for form Password type.
1617
#[deprecated(since = "0.3.0", note = "use `cot::form::types::Password` instead")]
1718
pub type Password = crate::form::types::Password;
1819
use crate::config::SecretKey;
@@ -511,12 +512,13 @@ impl PasswordHash {
511512
/// # Examples
512513
///
513514
/// ```
514-
/// use cot::auth::{Password, PasswordHash};
515+
/// use cot::auth::PasswordHash;
516+
/// use cot::form::types::Password;
515517
///
516518
/// let hash = PasswordHash::from_password(&Password::new("password"));
517519
/// ```
518520
#[must_use]
519-
pub fn from_password(password: &Password) -> Self {
521+
pub fn from_password(password: &crate::form::types::Password) -> Self {
520522
let hash = password_auth::generate_hash(password.as_str());
521523

522524
if hash.len() > MAX_PASSWORD_HASH_LENGTH as usize {
@@ -538,7 +540,8 @@ impl PasswordHash {
538540
/// # Examples
539541
///
540542
/// ```
541-
/// use cot::auth::{Password, PasswordHash, PasswordVerificationResult};
543+
/// use cot::auth::{PasswordHash, PasswordVerificationResult};
544+
/// use cot::form::types::Password;
542545
///
543546
/// let password = Password::new("password");
544547
/// let hash = PasswordHash::from_password(&password);
@@ -552,7 +555,7 @@ impl PasswordHash {
552555
/// PasswordVerificationResult::Invalid => println!("Password is invalid"),
553556
/// }
554557
/// ```
555-
pub fn verify(&self, password: &Password) -> PasswordVerificationResult {
558+
pub fn verify(&self, password: &crate::form::types::Password) -> PasswordVerificationResult {
556559
const VALID_ERROR_STR: &str = "password hash should always be valid if created with `PasswordHash::new` or `PasswordHash::from_password`";
557560

558561
match password_auth::verify_password(password.as_str(), &self.0) {
@@ -681,117 +684,6 @@ impl ToDbValue for PasswordHash {
681684
}
682685
}
683686

684-
/// A password.
685-
///
686-
/// It is always recommended to store passwords in memory using this newtype
687-
/// instead of a raw String, as it has a [`Debug`] implementation that hides
688-
/// the password value.
689-
///
690-
/// For persisting passwords in the database, and verifying passwords against
691-
/// the hash, use [`PasswordHash`].
692-
///
693-
/// # Security
694-
///
695-
/// The implementation of the [`Debug`] trait for this type hides the password
696-
/// value to prevent it from being leaked in logs or other debug output.
697-
///
698-
/// ## Password Comparison
699-
///
700-
/// When comparing passwords, there are two recommended approaches:
701-
///
702-
/// 1. The most secure approach is to use [`PasswordHash::from_password`] to
703-
/// create a hash from one password, and then use [`PasswordHash::verify`] to
704-
/// compare it with the other password. This method uses constant-time
705-
/// equality comparison, which protects against timing attacks.
706-
///
707-
/// 2. An alternative is to use the [`Password::as_str`] method and compare the
708-
/// strings directly. This approach uses non-constant-time comparison, which
709-
/// is less secure but may be acceptable in certain legitimate use cases
710-
/// where the security tradeoff is understood, e.g., when you're creating a
711-
/// user registration form with the "retype your password" field, where both
712-
/// passwords come from the same source anyway.
713-
///
714-
/// # Examples
715-
///
716-
/// ```
717-
/// use cot::auth::Password;
718-
///
719-
/// let password = Password::new("pass");
720-
/// assert_eq!(&format!("{:?}", password), "Password(\"**********\")");
721-
/// ```
722-
#[derive(Clone)]
723-
pub struct Password(String);
724-
725-
impl Debug for Password {
726-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
727-
f.debug_tuple("Password").field(&"**********").finish()
728-
}
729-
}
730-
731-
impl Password {
732-
/// Creates a new password object.
733-
///
734-
/// # Examples
735-
///
736-
/// ```
737-
/// use cot::auth::Password;
738-
///
739-
/// let password = Password::new("password");
740-
/// ```
741-
#[must_use]
742-
pub fn new<T: Into<String>>(password: T) -> Self {
743-
Self(password.into())
744-
}
745-
746-
/// Returns the password as a string.
747-
///
748-
/// # Examples
749-
///
750-
/// ```
751-
/// use cot::auth::Password;
752-
///
753-
/// let password = Password::new("password");
754-
/// assert_eq!(password.as_str(), "password");
755-
/// ```
756-
#[must_use]
757-
pub fn as_str(&self) -> &str {
758-
&self.0
759-
}
760-
761-
/// Consumes the object and returns the password as a string.
762-
///
763-
/// # Examples
764-
///
765-
/// ```
766-
/// use cot::auth::Password;
767-
///
768-
/// let password = Password::new("password");
769-
/// assert_eq!(password.into_string(), "password");
770-
/// ```
771-
#[must_use]
772-
pub fn into_string(self) -> String {
773-
self.0
774-
}
775-
}
776-
777-
impl From<&Password> for Password {
778-
fn from(password: &Password) -> Self {
779-
password.clone()
780-
}
781-
}
782-
783-
impl From<&str> for Password {
784-
fn from(password: &str) -> Self {
785-
Self::new(password)
786-
}
787-
}
788-
789-
impl From<String> for Password {
790-
fn from(password: String) -> Self {
791-
Self::new(password)
792-
}
793-
}
794-
795687
/// Authentication helper structure.
796688
///
797689
/// This is an object that provides methods to sign users in and out, by using

cot/src/form/types.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,22 @@ const MAX_EMAIL_LENGTH: u32 = 254;
3131
/// The implementation of the [`Debug`] trait for this type hides the password
3232
/// value to prevent it from being leaked in logs or other debug output.
3333
///
34+
/// ## Password Comparison
35+
///
36+
/// When comparing passwords, there are two recommended approaches:
37+
///
38+
/// 1. The most secure approach is to use [`PasswordHash::from_password`] to
39+
/// create a hash from one password, and then use [`PasswordHash::verify`] to
40+
/// compare it with the other password. This method uses constant-time
41+
/// equality comparison, which protects against timing attacks.
42+
///
43+
/// 2. An alternative is to use the [`Password::as_str`] method and compare the
44+
/// strings directly. This approach uses non-constant-time comparison, which
45+
/// is less secure but may be acceptable in certain legitimate use cases
46+
/// where the security tradeoff is understood, e.g., when you're creating a
47+
/// user registration form with the "retype your password" field, where both
48+
/// passwords come from the same source anyway.
49+
///
3450
/// # Examples
3551
///
3652
/// ```

0 commit comments

Comments
 (0)