feat(tokens): implemented token validation

This commit is contained in:
antifallobst 2023-08-16 20:05:19 +02:00
parent d3c721fb78
commit e3ea93f4ae
Signed by: antifallobst
GPG Key ID: 2B4F402172791BAF
2 changed files with 61 additions and 21 deletions

View File

@ -15,7 +15,7 @@ pub async fn start(port: u16, pool: MySqlPool) -> Result<()> {
sqlx::query!( sqlx::query!(
r#" r#"
CREATE TABLE IF NOT EXISTS Accounts ( CREATE TABLE IF NOT EXISTS Accounts (
id INT NOT NULL AUTO_INCREMENT, id INT8 UNSIGNED NOT NULL AUTO_INCREMENT,
username VARCHAR(32) NOT NULL, username VARCHAR(32) NOT NULL,
email TEXT NOT NULL, email TEXT NOT NULL,
salt VARCHAR(22) NOT NULL, salt VARCHAR(22) NOT NULL,
@ -33,7 +33,7 @@ pub async fn start(port: u16, pool: MySqlPool) -> Result<()> {
r#" r#"
CREATE TABLE IF NOT EXISTS AuthTokens ( CREATE TABLE IF NOT EXISTS AuthTokens (
token VARCHAR(32) NOT NULL, token VARCHAR(32) NOT NULL,
account INT NOT NULL, account INT8 UNSIGNED NOT NULL,
expire DATETIME NOT NULL expire DATETIME NOT NULL
); );
"# "#
@ -45,7 +45,7 @@ pub async fn start(port: u16, pool: MySqlPool) -> Result<()> {
r#" r#"
CREATE TABLE IF NOT EXISTS VerificationTokens ( CREATE TABLE IF NOT EXISTS VerificationTokens (
token VARCHAR(32) NOT NULL, token VARCHAR(32) NOT NULL,
account INT NOT NULL, account INT8 UNSIGNED NOT NULL,
expire DATETIME NOT NULL expire DATETIME NOT NULL
); );
"# "#

View File

@ -1,10 +1,11 @@
use anyhow::{Error, Result}; use anyhow::{Error, Result};
use sqlx::{mysql::MySqlPool, types::chrono as sqlx_chrono}; use sqlx::{mysql::MySqlPool, types::chrono as sqlx_chrono};
#[derive(Debug)]
pub struct AuthToken { pub struct AuthToken {
token: String, token: String,
account: i64, account: u64,
expire: sqlx_chrono::DateTime<chrono::Utc>, expire: sqlx_chrono::NaiveDateTime,
} }
impl AuthToken { impl AuthToken {
@ -13,7 +14,10 @@ impl AuthToken {
account_id: usize, account_id: usize,
lifetime: chrono::Duration, lifetime: chrono::Duration,
) -> Result<Self> { ) -> Result<Self> {
let expire = match sqlx_chrono::Utc::now().checked_add_signed(lifetime) { let expire = match sqlx_chrono::Utc::now()
.naive_utc()
.checked_add_signed(lifetime)
{
Some(e) => e, Some(e) => e,
None => { None => {
return Err(Error::msg( return Err(Error::msg(
@ -24,7 +28,7 @@ impl AuthToken {
let token = Self { let token = Self {
token: uuid::Uuid::new_v4().simple().to_string(), token: uuid::Uuid::new_v4().simple().to_string(),
account: account_id as i64, account: account_id as u64,
expire, expire,
}; };
@ -41,12 +45,29 @@ impl AuthToken {
Ok(token) Ok(token)
} }
pub async fn check(pool: &MySqlPool, token: String) -> Result<Option<Self>> {
let query_result = sqlx::query!(r#"SELECT * FROM AuthTokens WHERE token = ?;"#, token)
.fetch_one(pool)
.await;
match query_result {
Ok(row) => Ok(Some(Self {
token: row.token,
account: row.account,
expire: row.expire,
})),
Err(sqlx::Error::RowNotFound) => Ok(None),
Err(e) => Err(Error::new(e)),
}
}
} }
#[derive(Debug)]
pub struct VerificationToken { pub struct VerificationToken {
token: String, token: String,
account: i64, account: u64,
expire: sqlx_chrono::DateTime<chrono::Utc>, expire: sqlx_chrono::NaiveDateTime,
} }
impl VerificationToken { impl VerificationToken {
@ -55,7 +76,10 @@ impl VerificationToken {
account_id: usize, account_id: usize,
lifetime: chrono::Duration, lifetime: chrono::Duration,
) -> Result<Self> { ) -> Result<Self> {
let expire = match sqlx_chrono::Utc::now().checked_add_signed(lifetime) { let expire = match sqlx_chrono::Utc::now()
.naive_utc()
.checked_add_signed(lifetime)
{
Some(e) => e, Some(e) => e,
None => { None => {
return Err(Error::msg( return Err(Error::msg(
@ -66,7 +90,7 @@ impl VerificationToken {
let token = Self { let token = Self {
token: uuid::Uuid::new_v4().simple().to_string(), token: uuid::Uuid::new_v4().simple().to_string(),
account: account_id as i64, account: account_id as u64,
expire, expire,
}; };
@ -83,4 +107,20 @@ impl VerificationToken {
Ok(token) Ok(token)
} }
pub async fn check(pool: &MySqlPool, token: String) -> Result<Option<Self>> {
let query_result = sqlx::query!(r#"SELECT * FROM VerificationTokens WHERE token = ?;"#, token)
.fetch_one(pool)
.await;
match query_result {
Ok(row) => Ok(Some(Self {
token: row.token,
account: row.account,
expire: row.expire,
})),
Err(sqlx::Error::RowNotFound) => Ok(None),
Err(e) => Err(Error::new(e)),
}
}
} }