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,13 +15,13 @@ 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,
password VARCHAR(96) NOT NULL, password VARCHAR(96) NOT NULL,
joined DATETIME NOT NULL, joined DATETIME NOT NULL,
verified BOOLEAN NOT NULL, verified BOOLEAN NOT NULL,
PRIMARY KEY(id) PRIMARY KEY(id)
); );
"# "#
@ -32,9 +32,9 @@ pub async fn start(port: u16, pool: MySqlPool) -> Result<()> {
sqlx::query!( sqlx::query!(
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
); );
"# "#
) )
@ -44,9 +44,9 @@ pub async fn start(port: u16, pool: MySqlPool) -> Result<()> {
sqlx::query!( sqlx::query!(
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)),
}
}
} }