generate token and save in database

This commit is contained in:
deneb 2024-02-10 13:07:36 +01:00
parent 62390aa0ad
commit 2a1b6bd8ae
4 changed files with 48 additions and 6 deletions

1
Cargo.lock generated
View file

@ -488,6 +488,7 @@ dependencies = [
"hmac", "hmac",
"ldap3", "ldap3",
"md-5", "md-5",
"rand",
"secrecy", "secrecy",
"serde", "serde",
"sqlx", "sqlx",

View file

@ -20,6 +20,7 @@ color-eyre = { version = "0.6.2" }
hmac = "0.12.1" hmac = "0.12.1"
ldap3 = { version = "0.11.3", default-features = false, features = ["tls-rustls"] } ldap3 = { version = "0.11.3", default-features = false, features = ["tls-rustls"] }
md-5 = "0.10.6" md-5 = "0.10.6"
rand = "0.8.5"
secrecy = { version = "0.8.0", features = ["serde"] } secrecy = { version = "0.8.0", features = ["serde"] }
serde = { version = "1.0.196", features = ["derive"] } serde = { version = "1.0.196", features = ["derive"] }
sqlx = { version = "0.7.3", features = ["runtime-tokio", "tls-rustls", "sqlite"] } sqlx = { version = "0.7.3", features = ["runtime-tokio", "tls-rustls", "sqlite"] }

View file

@ -1,10 +1,11 @@
use std::sync::Arc; use std::sync::Arc;
use rand::{seq::IteratorRandom, thread_rng};
use tokio::sync::Mutex; use tokio::sync::Mutex;
use tracing::instrument; use tracing::{event, instrument, Level};
use crate::{ use crate::{
db::{/* Database, */ SqliteDatabase}, db::{/* Database, */ Database, SqliteDatabase},
secrets::{Password, UserToken}, secrets::{Password, UserToken},
}; };
@ -20,7 +21,25 @@ impl Authenticator {
#[instrument] #[instrument]
pub async fn create_user_token(&mut self, username: &str, password: &Password) -> UserToken { pub async fn create_user_token(&mut self, username: &str, password: &Password) -> UserToken {
todo!() // let created =
let mut token_str = "".to_owned();
let mut rng = thread_rng();
for _ in 0..30 {
let digit = (0..=15).choose(&mut rng).unwrap();
let char = (('a' as u8) + digit) as char;
token_str.push(char)
}
let new_token = UserToken::from(token_str);
let mut db = self.db.lock().await;
if let Err(err) = db.save_token(username, &new_token).await {
event!(Level::ERROR, %err, "Failed to save token in database");
}
new_token
} }
#[instrument] #[instrument]

View file

@ -1,3 +1,4 @@
use secrecy::ExposeSecret;
use sqlx::{query, query_as, Connection, SqliteConnection}; use sqlx::{query, query_as, Connection, SqliteConnection};
use crate::secrets::UserToken; use crate::secrets::UserToken;
@ -5,8 +6,12 @@ use crate::secrets::UserToken;
// TODO: allow configuring this via envar // TODO: allow configuring this via envar
const DB_URI_DEFAULT: &str = "sqlite://sqlite.db"; const DB_URI_DEFAULT: &str = "sqlite://sqlite.db";
const TABLE_USER_TOKENS: &str = "user_tokens";
pub trait Database { pub trait Database {
async fn get_token(&mut self, username: &str) -> Result<UserToken, sqlx::Error>; async fn get_token(&mut self, username: &str) -> Result<UserToken, sqlx::Error>;
async fn save_token(&mut self, username: &str, token: &UserToken) -> Result<(), sqlx::Error>;
} }
#[derive(Debug)] #[derive(Debug)]
@ -29,8 +34,8 @@ impl SqliteDatabase {
pub async fn init(&mut self) { pub async fn init(&mut self) {
query( query(
"CREATE TABLE IF NOT EXISTS user_tokens ( "CREATE TABLE IF NOT EXISTS {TABLE_USER_TOKENS} (
id INTEGER PRIMARY KEY NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT,
username VARCHAR(255), username VARCHAR(255),
token NCHAR(30), token NCHAR(30),
created DATETIME, created DATETIME,
@ -49,7 +54,7 @@ impl Database for SqliteDatabase {
"SELECT token "SELECT token
FROM user_tokens FROM user_tokens
WHERE WHERE
username = {username} username = ?
AND valid = TRUE AND valid = TRUE
ORDER BY ORDER BY
created DESC", created DESC",
@ -60,4 +65,20 @@ impl Database for SqliteDatabase {
Ok(UserToken::from(row.0)) Ok(UserToken::from(row.0))
} }
async fn save_token(&mut self, username: &str, token: &UserToken) -> Result<(), sqlx::Error> {
query(
"INSERT INTO {TABLE_USER_TOKENS}
(username, token, created, valid)
VALUES
(?, ?, DATETIME('NOW'), TRUE)
",
)
.bind(username)
.bind(token.0.expose_secret())
.execute(&mut self.conn)
.await?;
Ok(())
}
} }