Pour tout problème contactez-nous par mail : support@froggit.fr | La FAQ | Rejoignez-nous sur le Chat 💬

Skip to content
Snippets Groups Projects
crypto.rs 3.31 KiB
Newer Older
  • Learn to ignore specific revisions
  • Pierre Jarriges's avatar
    Pierre Jarriges committed
    use magic_crypt::{MagicCrypt, MagicCryptTrait, SecureBit};
    use rand::{distributions::Alphanumeric, Rng};
    
    #[derive(Debug, Clone)]
    /// A structure responsible of encrypting and decrypting data such as auth token, passwords and email addresses.
    pub struct Encryption {
        /// The encryption key must be keeped secret and is loaded from the $CRYPT_KEY environment variable
        pub key: String,
    }
    
    impl Encryption {
        pub fn new(key: String) -> Self {
            Encryption { key }
        }
    
        /// Gets a string as an argument and returns a base64 hash of the string based on the secret key and magic_crypt::SecureBit::Bit256 algorithm
        pub fn encrypt(&self, source: &String) -> String {
            let mc = MagicCrypt::new(&self.key, SecureBit::Bit256, None::<String>);
            mc.encrypt_str_to_base64(source)
        }
    
        /// Gets a string base64 hash as an argument and returns the decryted string.
        /// Panics if the source base64 string cannot be decrypted (should happen if trying to decrypt a regular string)
        #[cfg(test)]
        pub fn decrypt(&self, source: &String) -> String {
            let mc = MagicCrypt::new(&self.key, SecureBit::Bit256, None::<String>);
            mc.decrypt_base64_to_string(source).unwrap()
        }
    
        /// Generates a random ascii lowercase string. Length being given as argument.
        pub fn random_ascii_lc_string(&self, length: usize) -> String {
            // Thanks to https://stackoverflow.com/questions/54275459/how-do-i-create-a-random-string-by-sampling-from-alphanumeric-characters#54277357
            rand::thread_rng()
                .sample_iter(&Alphanumeric)
                .take(length)
                .map(char::from)
                .collect::<String>()
                .to_ascii_lowercase()
        }
    }
    
    /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@
     *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@
     *  _______   ______    ______   _______   *@@
     * |__   __@ |  ____@  /  ____@ |__   __@  *@@
     *    |  @   |  @__    \_ @_       |  @    *@@
     *    |  @   |   __@     \  @_     |  @    *@@
     *    |  @   |  @___   ____\  @    |  @    *@@
     *    |__@   |______@  \______@    |__@    *@@
     *                                         *@@
     *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@
     *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@*/
    
    #[cfg(test)]
    mod test_encryption {
        use super::*;
    
        #[test]
        fn test_random_ascii_lc_string() {
            dotenv::dotenv().ok();
            let key = std::env::var("CRYPT_KEY").unwrap();
            let enc = Encryption::new(key);
            let rdm_str = enc.random_ascii_lc_string(32);
            assert_eq!(rdm_str.len(), 32);
            assert!(rdm_str.chars().all(char::is_alphanumeric));
            assert_eq!(rdm_str, rdm_str.to_lowercase());
        }
    
        #[test]
        fn test_encrypt() {
            dotenv::dotenv().ok();
            let key = std::env::var("CRYPT_KEY").unwrap();
            let enc = Encryption::new(key);
    
            let an_email = String::from("kuadrado-email@test.com");
            let email_hash = enc.encrypt(&an_email);
            assert_ne!(an_email, email_hash);
        }
    
        #[test]
        fn test_decrypt() {
            dotenv::dotenv().ok();
            let key = std::env::var("CRYPT_KEY").unwrap();
            let enc = Encryption::new(key);
    
            let an_email = String::from("kuadrado-email@test.com");
            let email_hash = enc.encrypt(&an_email);
            let decrypted = enc.decrypt(&email_hash);
            assert_eq!(an_email, decrypted);
        }
    }