You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
yuurei/src/state/user.rs

62 lines
1.5 KiB

//! Used to determine which post belongs to who.
//!
//! Mostly for determining if a poster owns a post.
use super::*;
use std::{
net::SocketAddr,
};
use cryptohelpers::sha256;
/// A user's unique ID.
///
/// This is composed by the user's address and their session ID.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct UserID(SocketAddr, session::SessionID);
static COUNTER: GlobalCounter = GlobalCounter::new();
impl UserID
{
/// Generate a token from this instance.
///
/// User tokens are deterministically generated and can be deterministically verified.
pub fn generate_token(&self) -> u64
{
let cnt = COUNTER.get();
let mut trunc = [0u8; std::mem::size_of::<u64>()];
let hash = GloballySalted::new(self).compute_sha256_hash();
bytes::move_slice(&mut trunc[..], hash.as_ref());
u64::from_le_bytes(trunc) ^ cnt
}
/// Validate a token for this instance created with `generate_token`.
pub fn validate_token(&self, val: u64) -> bool
{
let mut trunc = [0u8; std::mem::size_of::<u64>()];
let hash = GloballySalted::new(self).compute_sha256_hash();
bytes::move_slice(&mut trunc[..], hash.as_ref());
COUNTER.valid(u64::from_le_bytes(trunc) ^ val)
}
}
/// A user not bound to a session.
#[derive(Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub struct User
{
addr: SocketAddr,
}
impl User
{
/// Get the user ID for this session.
pub fn id_for_session(&self, session: &session::Session) -> UserID
{
UserID(self.addr, session.session_id().clone())
}
}