    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    use std::convert::TryInto;

    use rand::{distributions::Alphanumeric, rngs::OsRng, Rng as _};

    use crate::storage::SessionKey;

    /// Session key generation routine that follows [OWASP recommendations].
    ///
    /// [OWASP recommendations]: https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html#session-id-entropy
    pub(crate) fn generate_session_key() -> SessionKey {
        let value = std::iter::repeat(())
            .map(|()| OsRng.sample(Alphanumeric))
            .take(64)
            .collect::<Vec<_>>();

        // These unwraps will never panic because pre-conditions are always verified
        // (i.e. length and character set)
        String::from_utf8(value).unwrap().try_into().unwrap()
    }