generate token and save in database
This commit is contained in:
parent
62390aa0ad
commit
2a1b6bd8ae
4 changed files with 48 additions and 6 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -488,6 +488,7 @@ dependencies = [
|
||||||
"hmac",
|
"hmac",
|
||||||
"ldap3",
|
"ldap3",
|
||||||
"md-5",
|
"md-5",
|
||||||
|
"rand",
|
||||||
"secrecy",
|
"secrecy",
|
||||||
"serde",
|
"serde",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
|
|
|
@ -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"] }
|
||||||
|
|
25
src/auth.rs
25
src/auth.rs
|
@ -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]
|
||||||
|
|
27
src/db.rs
27
src/db.rs
|
@ -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(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue