From 3d79b674cec3732efb5da472e9816d55f5aa2f14 Mon Sep 17 00:00:00 2001 From: Jacobtread Date: Sun, 16 Jun 2024 21:16:03 +1200 Subject: [PATCH] feat: randomly generated login codes --- src/services/sessions.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/services/sessions.rs b/src/services/sessions.rs index 690aa6e..ac33517 100644 --- a/src/services/sessions.rs +++ b/src/services/sessions.rs @@ -8,6 +8,9 @@ use crate::utils::types::PlayerID; use base64ct::{Base64UrlUnpadded, Encoding}; use hashbrown::HashMap; use parking_lot::Mutex; +use rand::distributions::Distribution; +use rand::rngs::StdRng; +use rand::{Rng, SeedableRng}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; use uuid::Uuid; @@ -45,6 +48,16 @@ pub struct LoginCodeData { /// relying on IP addresses: https://github.com/PocketRelay/Server/issues/64#issuecomment-1867015578 pub type AssociationId = Uuid; +/// Rand distribution for a logic code part +struct LoginCodePart; + +impl Distribution for LoginCodePart { + fn sample(&self, rng: &mut R) -> char { + let chars = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + let idx = rng.gen_range(0..chars.len()); + chars[idx] as char + } +} impl Sessions { /// Expiry time for tokens const EXPIRY_TIME: Duration = Duration::from_secs(60 * 60 * 24 * 30 /* 30 Days */); @@ -64,7 +77,13 @@ impl Sessions { /// Creates a new login code for the provider player, returns the /// login code storing the data so it can be exchanged pub fn create_login_code(&self, player_id: PlayerID) -> Result { - let code: LoginCode = "ACC123".to_string(); + let rng = StdRng::from_entropy(); + + let code: LoginCode = rng + .sample_iter(&LoginCodePart) + .take(5) + .map(char::from) + .collect(); // Compute expiry timestamp let exp = SystemTime::now()