From 379e97c2cb145bc3a495aa14746273d83b508214 Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Sat, 19 Oct 2024 01:51:30 -0400 Subject: Unicode normalization on input. This normalizes the following values: * login names * passwords * channel names * message bodies, because why not The goal here is to have a canonical representation of these values, so that, for example, the service does not inadvertently host two channels whose names are semantically identical but differ in the specifics of how diacritics are encoded, or two users whose names are identical. Normalization is done on input from the wire, using Serde hooks, and when reading from the database. The `crate::nfc::String` type implements these normalizations (as well as normalizing whenever converted from a `std::string::String` generally). This change does not cover: * Trying to cope with passwords that were created as non-normalized strings, which are now non-verifiable as all the paths to verify passwords normalize the input. * Trying to ensure that non-normalized data in the database compares reasonably to normalized data. Fortunately, we don't _do_ very many string comparisons (I think only login names), so this isn't a huge deal at this stage. Login names will probably have to Get Fixed later on, when we figure out how to handle case folding for login name verification. --- src/token/app.rs | 4 ++-- src/token/repo/auth.rs | 6 +++--- src/token/repo/token.rs | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/token') diff --git a/src/token/app.rs b/src/token/app.rs index 0dc1a46..d4dd1a0 100644 --- a/src/token/app.rs +++ b/src/token/app.rs @@ -12,7 +12,7 @@ use super::{ use crate::{ clock::DateTime, db::NotFound as _, - login::{Login, Password}, + login::{Login, Name, Password}, }; pub struct Tokens<'a> { @@ -27,7 +27,7 @@ impl<'a> Tokens<'a> { pub async fn login( &self, - name: &str, + name: &Name, password: &Password, login_at: &DateTime, ) -> Result<(Login, Secret), LoginError> { diff --git a/src/token/repo/auth.rs b/src/token/repo/auth.rs index 88d0878..c621b65 100644 --- a/src/token/repo/auth.rs +++ b/src/token/repo/auth.rs @@ -3,7 +3,7 @@ use sqlx::{sqlite::Sqlite, SqliteConnection, Transaction}; use crate::{ clock::DateTime, event::{Instant, Sequence}, - login::{self, password::StoredHash, History, Login}, + login::{self, password::StoredHash, History, Login, Name}, }; pub trait Provider { @@ -19,12 +19,12 @@ impl<'c> Provider for Transaction<'c, Sqlite> { pub struct Auth<'t>(&'t mut SqliteConnection); impl<'t> Auth<'t> { - pub async fn for_name(&mut self, name: &str) -> Result<(History, StoredHash), sqlx::Error> { + pub async fn for_name(&mut self, name: &Name) -> Result<(History, StoredHash), sqlx::Error> { let found = sqlx::query!( r#" select id as "id: login::Id", - name, + name as "name: Name", password_hash as "password_hash: StoredHash", created_sequence as "created_sequence: Sequence", created_at as "created_at: DateTime" diff --git a/src/token/repo/token.rs b/src/token/repo/token.rs index c592dcd..960bb72 100644 --- a/src/token/repo/token.rs +++ b/src/token/repo/token.rs @@ -3,7 +3,7 @@ use uuid::Uuid; use crate::{ clock::DateTime, - login::{self, History, Login}, + login::{self, History, Login, Name}, token::{Id, Secret}, }; @@ -128,7 +128,7 @@ impl<'c> Tokens<'c> { select token.id as "token_id: Id", login.id as "login_id: login::Id", - login.name as "login_name" + login.name as "login_name: Name" from login join token on login.id = token.login where token.secret = $1 -- cgit v1.2.3